FHIR Bundle Explorer
NEW!

FHIR Bundle Explorer

Open a FHIR Bundle, resource or Bulk Data NDJSON in your browser. Browse resources as a tree, flatten them to a table, and export CSV. 100% private.

HL7 Tools
πŸ”’ A FHIR Bundle is patient data. Everything is parsed in your browser β€” nothing is uploaded, and references are resolved locally, never fetched from a server.

Examples

Keywords

fhir bundle viewerfhir to csvflatten fhir jsonfhir bulk export ndjson vieweropen ndjson fhirfhir bundle explorer

Need something else?

How to use

1

Paste a FHIR Bundle, a single resource, or NDJSON from a Bulk Data export into the input box. You can also upload or drop a .json or .ndjson file. The format is detected automatically, so you do not need to tell the tool which one you have.

2

Read the summary line. It reports how many resources were found, which format was detected, and a count per resource type, plus any parse problems with the line number where they occurred.

3

Use the Tree tab to browse. Filter by resource type or search across every value, expand a resource to see its fields, and click a reference such as Patient/pt-1 to jump straight to the resource it points at.

4

Switch to the Table tab to flatten one resource type into rows and columns. Choose whether repeated values are joined with a semicolon or expanded to one row each, switch between preset and all columns, then download the result as CSV.

Features

Three Input Formats, Auto-Detected

Accepts a Bundle, a bare resource that is not wrapped in a Bundle, and NDJSON from a FHIR Bulk Data export where each line is a separate resource. A plain JSON array of resources is accepted too, because that is what you get when you collapse an NDJSON export with a tool like jq.

References Resolved Locally

Every reference in the data is indexed and matched against the resources you supplied, whether it is written as Patient/123, as a urn:uuid pointing at an entry's fullUrl, or as an absolute URL ending in the same type and id. Resolved references become clickable; references that point outside your data are shown as unresolved rather than quietly dropped.

Flattening That Does Not Lose Data

Array indices are collapsed so every value of a repeating field lands in one column. By default each resource is one row with repeats joined by a semicolon; switch to expand mode and each repeat becomes its own row, with single-valued columns repeated down so every row stays readable on its own.

Presets With an Escape Hatch

Nine common resource types have curated columns, filtered down to the paths actually present in your data so you never see a column of empty cells. Any other resource type gets columns derived from the most populated paths in what you pasted, and a single switch reveals every discovered path.

Built for Large Exports

Only the visible slice of table rows is kept in the DOM, so a table of thousands of rows scrolls without freezing the tab. Input is capped at 25 MB and 20,000 resources, and when a cap is reached the tool states exactly how many resources were dropped instead of silently truncating.

Why Choose This Tool?

Patient Data Never Leaves Your Browser

A real FHIR Bundle is patient data β€” names, identifiers, diagnoses, medications. Everything here is parsed locally and nothing is uploaded. References are resolved against the resources you supplied and are never fetched from a server, so no part of your payload leaks through a background request.

Answers the Two Questions You Actually Have

When a Bundle lands on your desk you need to know what is inside it and to get some of it into a spreadsheet. The tree answers the first and the flattened table answers the second, both from a single parse, so you are not pasting the same payload into two different tools.

Handles Bulk Data Exports

FHIR Bulk Data exports arrive as NDJSON files with thousands of resources per file, which is exactly the case where opening the file by hand stops being realistic. This tool reads NDJSON directly, reports the line number of any broken record, and keeps every good line rather than failing the whole file.

Nothing Is Hidden From You

Curated columns make the first view readable, but you can always switch to every discovered path, pick columns yourself, and see the unresolved references and parse issues laid out explicitly. The tool aims to be a fast lens on your data, never an opinionated filter that quietly decides what matters.

Understanding FHIR Bundles, References, and What It Means to Flatten Them

What a Bundle Actually Is

A Bundle is FHIR's envelope. Rather than a resource describing a clinical fact, it is a container that carries other resources, and the type field tells you why they were grouped. A searchset is the answer to a query against a FHIR server. A transaction is a set of changes to apply together, each entry carrying a request that says whether to POST, PUT or DELETE. A collection is simply a bag of resources with no processing semantics. A document is a fixed, signed composition. The entries themselves live under entry, each one an object with an optional fullUrl and a resource.

Why References Are the Hard Part

Resources in a Bundle are not independent rows; they form a graph. An Observation points at its subject, an Encounter points at the patient and the service provider, a Condition points at both. That pointer is a reference, and FHIR permits several ways to write one. The most familiar is a relative reference such as Patient/pt-1, which names a resource type and id. Inside transaction Bundles, where resources have not been assigned server ids yet, entries are addressed by a fullUrl holding a urn:uuid: value, and references point at that urn. References can also be absolute URLs on a server you may not have access to.

This explorer builds a lookup table from every resource you supplied, keyed by its Type/id, its bare id, its fullUrl, and the trailing Type/id of that fullUrl. Each reference in the data is then matched against that table. When a match is found the reference becomes a link you can click, and the target resource records that it is referenced by the source, so you can navigate the graph in both directions. When no match is found β€” because the reference points at a resource on a server, or at an entry that was not included in the export β€” it is reported as unresolved. That distinction matters: an unresolved reference is often the actual bug you are hunting, and a tool that hid it would be hiding your problem.

Crucially, resolution happens only against the data you pasted. A Bundle is protected health information, and a tool that dereferenced https://ehr.example.org/fhir/Patient/123 to show you a nicer label would be transmitting your payload's contents to a third party. Nothing here makes a network request.

What Flattening Means, and What It Costs

FHIR resources are deeply nested trees, and spreadsheets are flat grids. Turning one into the other always involves a trade, and the honest question is which trade you are making. Consider a Patient with two given names. In the raw JSON the values sit at name[0].given[0] and name[0].given[1]. A literal flattening would create two columns for those two positions β€” and a third the moment a patient has a middle name, and a fourth for the next edge case. Real resources have around forty leaf paths, so this approach produces hundreds of sparse columns and a spreadsheet nobody can use.

This tool takes the other route: array indices are collapsed, so both given names belong to the column name.given. The values are then either joined into one cell, separated by a semicolon, or expanded so each occupies its own row. Join mode keeps the promise that one row equals one resource, which is what you want when counting patients or pivoting by gender. Expand mode keeps the promise that one cell holds one value, which is what you want when each repeat is itself the unit of analysis β€” the components of a blood-pressure Observation, or the codings of a diagnosis. In expand mode, single-valued columns repeat down the generated rows so that every row remains self-describing rather than leaving the patient id blank on all but the first line.

How the Columns Are Chosen

Nine resource types that dominate real bundles β€” Patient, Observation, Condition, Encounter, MedicationRequest, Procedure, AllergyIntolerance, Immunization and DiagnosticReport β€” have hand-picked column sets covering the fields people actually analyse. Those presets are then filtered against your data, so if none of your Patients carry an address you will not be shown empty address columns. For every other resource type, and for a curated type whose preset finds nothing, columns are derived from your data instead: each leaf path is counted across the resources of that type, and the most populated paths are shown. That way a ResearchStudy or a Coverage still produces a sensible table without anyone hand-maintaining a preset for all one hundred and fifty resource types in the specification.

Some keys are deliberately excluded from flattening because they add noise rather than signal: meta, the narrative text block and its embedded XHTML, and extension arrays. If you need those, the tree view shows the resource as supplied.

Bulk Data and NDJSON

When a FHIR server exports a population rather than answering a query, it uses the Bulk Data specification, and the output is not a Bundle at all. It is NDJSON: newline-delimited JSON, one complete resource per line, usually one file per resource type. The format exists because a million-patient export cannot be held in memory as a single JSON document, and each line can be streamed and processed independently. That same property is what lets this tool report a malformed line by number and keep every other line, rather than discarding an entire export because one record is broken.

Where This Tool Stops

This is a read-only explorer. It does not check whether your resources conform to FHIR β€” for that, use the FHIR Resource Validator, which checks required fields, cardinality, data types and value-set bindings against R4. It does not edit resources or send them anywhere. And it reads JSON, not XML, matching how the overwhelming majority of current FHIR traffic is exchanged. If your data started life as HL7 v2, the HL7 v2 to FHIR Mapper converts it first, and the result can be explored here.

Frequently Asked Questions

Is my FHIR Bundle uploaded anywhere?

No. The file is read and parsed entirely in your browser, and no part of it is sent over the network. This matters more here than for most tools because a Bundle typically contains protected health information. References are resolved only against the resources you supplied β€” the tool never fetches a referenced resource from a server, which would transmit your data. You can confirm this by watching your browser's network tab while exploring a bundle.

What input formats are supported?

Four, all detected automatically: a Bundle resource, a single bare resource that is not wrapped in a Bundle, NDJSON where each line is a separate resource, and a plain JSON array of resources. The last two cover FHIR Bulk Data exports and the output of collapsing such an export with a tool like jq.

What happens if one line of my NDJSON file is broken?

That line is reported as an issue with its line number, and every other line is still parsed. A bulk export of thousands of records is not discarded because one record is malformed. The same applies to a Bundle entry that carries no usable resource: it is skipped with a warning and the rest of the bundle is explored normally.

How are repeated values handled in the table?

By default each resource becomes one row and repeated values are joined with a semicolon, so a patient with two given names shows Ada;Augusta in a single cell. Switching to expand mode gives each repeated value its own row, with single-valued columns repeated down so every row is still self-describing. Neither mode discards data β€” they differ in whether you want one row per resource or one value per cell.

Why does my table not show every field in the resource?

Common resource types start with a curated set of columns so the first view is readable, and that set is filtered to the paths actually present in your data. Switch the column selector to show all columns and every leaf path discovered in your data appears. The meta block, the narrative text block and extensions are excluded from flattening as noise; the tree view shows the resource as supplied.

What does it do with a resource type it has no preset for?

It derives one. Every leaf path is counted across the resources of that type in your data, and the most populated paths become the columns. A ResearchStudy, a Coverage or a custom profile therefore still produces a usable table, and you can switch to all columns at any point.

Can it open a very large Bulk Data export?

Up to a point, and it is explicit about that point. Input is capped at 25 MB and 20,000 resources. When a cap is reached the summary states how many resources were dropped rather than silently truncating, so you never mistake a partial view for a complete one. Table rows are rendered in a moving window, so scrolling thousands of rows stays smooth.

Why are some references shown in red as unresolved?

Because they point at something not present in the data you supplied β€” typically a resource that lives on a server, or an entry missing from the export. They are shown rather than hidden because an unresolved reference is frequently the actual problem you are investigating, such as a transaction bundle that forgot to include a referenced Practitioner.

Does it validate my resources?

No, and that is a deliberate boundary. This tool answers what is in the bundle and how do I get it into a spreadsheet. Whether the resources conform to FHIR R4 β€” required fields, cardinality, data types, value sets β€” is answered by the FHIR Resource Validator, which is a separate tool on this site.

Is the CSV export safe to open in Excel?

Yes. Cells beginning with =, +, - or @ can be executed as formulas by Excel, Google Sheets and LibreOffice, and FHIR string fields such as a patient name are attacker-influenceable. The export prefixes such cells with a tab so the text stays readable but is never evaluated, and applies RFC 4180 quoting throughout.

Does it support FHIR XML?

No, JSON only. The overwhelming majority of current FHIR R4 traffic is exchanged as JSON, and Bulk Data exports are JSON by specification. If you have XML resources you will need to convert them before exploring them here.

Related Articles

Learn more