Open source
Open-source FHIR validation in TypeScript.
Check FHIR resources against your selected profiles and rules, and get findings you can trace to an element and validation basis. Use the engine from a terminal, in TypeScript or in CI.
Apache-2.0 · v0.8.0 · FHIR R4, R4B, R5 and R6
Dated comparison reports include unresolved differences and do not establish a score for the current npm release. Review coverage and evidence.
Resolve, validate, explain
Keep the selected validation basis and the resulting findings connected.
- Step 1 of 3.
Resolve
Fix the FHIR release, profiles, packages, terminology and rules before checking the resource.
- Step 2 of 3.
Validate
Run independently configurable checks against that selected validation basis.
- Step 3 of 3.
Explain
Return findings with severity, element path and diagnostic context for review.
Example from the recorded R4 run: one blocking type finding, with its validation basis. Informational findings are omitted here.
FHIR Patient
R4 · active: "yes"
Pinned validation basis
R4 Patient profile · core package 4.0.1
TypeScript engine
Independently configurable checks
- Structural
- Profile
- Terminology
- Reference
- Invariant
- Custom rules
- Metadata
- Anomaly
Type mismatch
Expected boolean; found string.
- Severity
- error
- Element path
- Patient.active
- Diagnostic code
- structural-primitive-type-mismatch
- Rule source
- R4 Patient · active: boolean
Three ways to run it
Apache-2.0, v0.8.0 on npm. FHIR R4, R4B, R5, and R6.
npx -p @records-fhir/validator@0.8.0 records-fhir-validator ./fixtures --fail-on=warningEight aspects, independently configurable
Each aspect can be enabled, tuned by severity, and read on its own. That separation is what makes a result diagnosable instead of just red.
| Structural | JSON structure, required fields, cardinality, type constraints |
|---|---|
| Profile | StructureDefinition conformance and discriminator-based slicing |
| Terminology | CodeSystem and ValueSet bindings, local expansion with server fallback |
| Reference | Reference existence, target type checking, circular detection |
| Invariant | FHIRPath constraints declared on StructureDefinitions |
| Custom rules | Your own FHIRPath business rules, plus advisor overrides |
| Metadata | FHIR meta completeness and security labels |
| Anomaly | Statistical outliers across a resource population |
Validation coverage & evidence
Diagnostic snapshot measured 2026-09-21, reviewed 2026-09-28. Unresolved differences remain; these case pass counts do not establish a score for the current npm release.
HL7 R4 JSON
Measured 2026-09-21
- Passed / run
- 383 / 385
- Failed
- 2
- Skipped
- 5
Two failures remain in the raw report; the workflow gate passes with explicit exceptions.
HL7 R4B JSON
Measured 2026-09-21
- Passed / run
- 8 / 8
- Failed
- 0
- Skipped
- 0
Eight measured compatibility cases; this is a small scope.
HL7 R5 JSON
Measured 2026-09-21
- Passed / run
- 134 / 138
- Failed
- 4
- Skipped
- 0
Four comparisons fail in this recorded run.
MII reference
Measured 2026-09-21
- Passed / run
- 137 / 150
- Failed
- 13
- Skipped
- 103
91 skips for incomplete reference terminology and 12 for unmapped corpus profiles. Failures need engine, comparator and terminology diagnosis.
EPS / HAPI
Measured 2026-09-21
- Passed / run
- 7 / 8
- Failed
- 1
- Skipped
- 0
One comparison misses additional-binding-unavailable coverage evidence. The separate local Records matrix is a different check.
The quality corpus detected 274/274 seeded issues. Precision was not established: a missing upstream fixture stopped the first clean-input check and later precision steps were skipped. A detection result alone does not measure false positives.
The workflow head was 61a4bca. R4 and R5 reports record dirty working trees and input digests; these measurements do not identify a certified current package. Inspect the dated summary, provenance and source hashes. The older selected archives remain separately described below.
Archived measurements, with their limits.
Historical HL7 and MII reports
The selected historical JSON report records 533 of 533 executed cases passing the harness threshold, with three runtime skips. Of those cases, 513 scored exact agreement and 20 retained differences.
Measured by Records 0.10.1 on 2026-08-25 against FHIR/fhir-test-cases at commit 8923095. Both the suite and the commit are public, and the source artifact is conformance-results/report-2026-08-24.json. The archive does not record the tested npm package versions or source revision. Its results cannot be assigned to the currently published v0.8.0 package.
The earlier 536/536 headline was withdrawn after profile-source loading defects were found in its harness. The archive separates passed thresholds, exact scores, residual differences, and skipped cases. Inspect the archived measurement summary and source hashes.
A second reference: the MII lane
Beyond the HL7 suite, Records is measured against the official mii reference validator: 231/231 archived reference cases passed on 2026-07-23, with 22 classified skips outside the measured lane. This separate archive does not certify a site, the MII programme, or the current npm package.
What the number does and does not mean
Passing the recorded harness threshold is different from exact agreement. The archive contains 513 exact scores and 20 residual differences, with 3 runtime skips. It does not mean support for every one of the 969 entries in the upstream manifest. 433 entries sit outside this lane, and they are listed below rather than folded into a friendlier percentage.
Excluded cases and unsupported lanes (433 entries)
Excluded manifest entries
Every one of the 433 excluded manifest entries, and why. A conformance number is only useful if its boundary is published with it.
XML resources
299 cases
The XML adapter ships; its Java-baseline score is a separate lane.
Adjacent standards (CDA, HL7 v2, CDS Hooks, SHC, XVer, DSIG, JSON5)
68 cases
Each needs a dedicated module and its own score.
Legacy FHIR versions (DSTU2, STU3)
47 cases
Out of scope unless legacy support becomes a product target.
Disabled upstream (`use-test: false`)
17 cases
Excluded by the upstream manifest itself.
No Java baseline declared
1 cases
An upstream teardown workaround, not a validator comparison.
Logical model test
1 cases
Awaiting a logical-model validation lane.
XML parsing, NDJSON input, and the FHIR Schema path all ship in the engine. They are reported as their own lanes rather than blended into the headline, because a single averaged percentage across unlike test classes is not a measurement.
Where the engine ends and Records begins
The boundary is deliberate and stated here rather than discovered later.
Apache-2.0
In the open engine
- The eight-aspect validation runtime
- StructureDefinition loading from FHIR packages
- FHIRPath invariant execution and slicing
- Terminology, reference, metadata, and Bundle validators
- OperationOutcome conversion, CLI, and GitHub Action
Commercial
In Records
- Continuous validation against live FHIR servers
- Baselines, deltas, and drift detection over time
- Quality gates, triage, and cross-server comparison
- Evidence reports with the reproducibility contract
- Workspaces, RBAC, and on-prem deployment
A validator answers is this valid now? Records answers the question a running system actually has: will we know when it stops being valid? The engine is the honest half of that — take it, embed it, fork it. The half that watches it over time is the product.
Choose your next step.
Run the open-source engine in your workflow, or explore continuous validation in Records.
