Diff-Friendly Formatting for Bundles Under Version Control
Bundles that live in version control — fixtures, examples, IG source, integration test data — deserve the same formatting discipline as source code. The formatter's job is not just readability. It is producing diffs that reviewers can actually review. A three-line-change diff that touches three fields is reviewable. A one-line-change diff that touches everything because indentation shifted is not. The site's FHIR JSON tidier is what you run before committing a Bundle. For the wider FHIR framing, more FHIR explainers on conecion has more.
Why Diffs Matter For Bundles
- Fixtures change over time — reviewers need to see what changed
- IG examples get updated — the change needs to survive review
- Integration test data drifts — regressions surface in diffs
- Regulatory submissions include Bundles — auditors read diffs
Every case is a diff-consumer. Formatting decides how legible the diff is.
One Element Per Line
The single most impactful diff-friendliness rule: put one element per line. Objects on multiple lines. Arrays on multiple lines when the elements are objects. Scalars on their own line when they are load-bearing.
That is the standard "pretty" mode. Every JSON formatter can do it. The tidier defaults to it.
For the base argument, why an unformatted Bundle costs you more time than a formatted one covers the format-first framing.
Consistent Indentation
Two-space or four-space indent — pick one, apply everywhere. Mixed indent produces diffs with whitespace changes that overwhelm the semantic changes.
The tool should always emit the same indent. The reviewer should never have to guess.
Preserve Order
Diffs assume the formatter did not reorder anything. If your formatter sorts keys, every commit that touches a Bundle produces a re-sort diff on top of the intended change. That is friction with no upside.
For the deeper mechanic, keeping resource order stable across pretty-printing is the entry.
Line-Length Discipline
Very long lines make diffs harder to read in code review tools. Line-wrap on strings when the string is long, break arrays across lines, avoid single lines that scroll horizontally.
Some formatters cap line length at 80 or 120 characters and wrap strings. Others do not. Pick one and stick with it. For the trade-off, line-length choices that survive code review is the entry.
Trailing Commas
JSON does not allow trailing commas. Some tools helpfully add them; they produce invalid JSON. Never trust a formatter that emits trailing commas — verify it round-trips to valid JSON.
Newline Conventions
- LF endings only (Unix)
- Final newline at end of file
- No trailing whitespace on lines
Standard code-source conventions. Apply to JSON just as you would to source code. Editors that add trailing whitespace or use CRLF produce noisy diffs.
Formatter Determinism
The same input should always produce the same output. Different formatters may disagree — pick one and use it across every Bundle in your repository. Mixing formatters produces re-format diffs every time a different developer commits.
The tidier at /playground/tidy-fhir-json/ is one deterministic option. If your team uses a different tool, standardize on it.
Pre-Commit Hooks
The right place to enforce formatting is a pre-commit hook that runs the formatter and rejects unformatted content. That way every commit lands formatted; every diff is meaningful.
Without the hook, formatting drift accumulates. With it, formatting stops being a review topic.
The Short Version
One element per line. Consistent indent. Preserve order. Cap line length. No trailing commas. LF endings. Deterministic formatter. Pre-commit hook. That is the diff-friendliness checklist. Everything else is bike-shedding.

Sources
- IETF RFC 8259 canonical JSON specification - IETF RFC 8259 canonical JSON specification
