Skip to content

FHIR Validator

Actions

About

Validate FHIR R4/R4B/R5/R6 JSON resources with the Records TypeScript validator
validator-v0.5.0
Latest
Star (2)

Records FHIR Validator

Pure TypeScript FHIR validator for CI pipelines, GitHub Actions, and standalone Node.js use. It validates FHIR JSON resources against StructureDefinitions, FHIRPath invariants, terminology bindings, references, slicing, extensions, Bundle rules, metadata, and optional custom rules without requiring a JVM, database, or Records server.

npm CI FHIR License HL7 parity MII scope FHIR Schema

Quick Start

GitHub Action

Use the floating major tag for the latest stable validator in the current major line:

name: Validate FHIR

on:
  pull_request:
  push:
    branches: [main]

jobs:
  fhir:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: medvertical/records-fhir-validator@v0
        with:
          paths: |
            examples/**/*.json
            test/fixtures/**/*.json
          fhir-version: R4
          fail-on: error

For production CI, pin an immutable patch tag:

- uses: medvertical/records-fhir-validator@v0.5.0
  with:
    paths: resources/**/*.json
    profile-url: http://hl7.org/fhir/StructureDefinition/Patient
    fhir-version: R4
    fail-on: error

Action pinning:

Goal Pin in uses: Notes
Latest stable in current major medvertical/records-fhir-validator@v0 Floating tag, force-moved on stable releases only
Exact released version medvertical/records-fhir-validator@v0.5.0 Immutable consumer tag
Bit-exact reproducibility medvertical/records-fhir-validator@<commit-sha> Best for audit and forensics

The validator-v<semver> tag is the npm mirror/release-page tag. Use v<semver> or a commit SHA for GitHub Action pins.

npm Package

npm install @records-fhir/validator@0.5.0 @records-fhir/validation-types@0.1.6

Run the CLI against one file or a folder:

npx -p @records-fhir/validator records-fhir-validator ./patient.json
npx -p @records-fhir/validator records-fhir-validator ./fixtures --fail-on=warning
npx -p @records-fhir/validator records-fhir-validator ./patient.json --format=json
npx -p @records-fhir/validator records-fhir-validator ./fixtures --summary-only --output validation-report.json

Useful CLI options:

Option Default Purpose
--profile-url <url> base profile for each resourceType Validate every resource against one canonical profile.
--fhir-version R4|R4B|R5|R6 R4 Select the public FHIR version.
--fail-on error|warning|none error Control the process exit threshold.
--format text|json text Print human-readable lines or structured JSON.
--output <file> stdout Write validation output to a file. Parent directories are created.
--summary-only off Omit per-issue output and print only aggregate counts.
--include <glob> **/*.json Include matching JSON files when walking folders. Repeatable or comma-separated.
--exclude <glob> none Exclude matching JSON files when walking folders. Repeatable or comma-separated.

CLI exit codes:

Code Meaning
0 Validation completed and did not meet the --fail-on threshold.
1 Validation completed and met the --fail-on threshold.
2 Invalid CLI input, unreadable paths, no matched JSON files, or output write failure.

Validate a resource from Node.js:

import { recordsValidator } from '@records-fhir/validator';

const issues = await recordsValidator.validate(
  { resourceType: 'Patient', id: 'example' },
  'http://hl7.org/fhir/StructureDefinition/Patient',
  'R4',
);

Optional offline profile packages can be loaded through the package APIs. The default public repository export intentionally excludes bundled third-party IG artifacts until their upstream licenses and notices have been reviewed.

Output Shape

The validator emits structured issues that are intended for CI annotations, database storage, and UI display:

{
  "severity": "warning",
  "code": "terminology-binding-preferred",
  "path": "Patient.gender",
  "message": "Code is outside the preferred value set."
}

The CLI text mode prints one issue per line and exits according to --fail-on. JSON mode returns { summary, results }, where each result includes file, resourceType, profileUrl, and issues. With --summary-only, JSON mode returns only { summary }.

What Is Included

  • @records-fhir/validator 0.5.0 - Apache-2.0 validation engine.
  • @records-fhir/validation-types 0.1.6 - Apache-2.0 validation-domain types.
  • Composite GitHub Action at repository root.
  • Standalone examples under packages/validator/examples/.
  • Boundary audit and smoke-test scripts.
  • Public conformance evidence artifacts under conformance-results/.

Repository Scope

Records itself is commercial closed-source software. This repository contains only the open-source validator packages extracted from Records.

This public repository must not contain the Records web application, Records API server, database schema, migrations, repositories, governance reports, customer integrations, environment files, or commercial deployment configuration.

@records-fhir/bundled-profiles is intentionally excluded from the default export until all bundled upstream FHIR and implementation-guide artifact licenses have been reviewed. Re-run the export with --include-bundled-profiles only after that review.

The validator packages are designed for standalone embedding. Host applications can provide optional profile, rule, persistence, and logging integrations through explicit package APIs.

Practical Scope

Use this project when you need a TypeScript-native validator that runs in Node, CI, GitHub Actions, or product backends without starting the Java validator. It is strongest for FHIR JSON resource validation, StructureDefinition constraints, slicing, references, terminology checks, and structured issue metadata that downstream applications can store or display.

It is not a universal FHIR ecosystem implementation. XML resources, CDA, HL7 v2, CDS Hooks, SHC, DSIG, JSON5 harnesses, legacy STU3/DSTU versions, logical models, and site-level MII certification are outside the current headline support scope unless called out by a dedicated conformance lane.

FHIR Version Support

The package supports public FHIR versions R4, R4B, R5, and R6. R4B routes through the R4 internal validation path because R4B is a maintenance release of R4 with compatible StructureDefinition and FHIRPath context for this validator mode.

Validation Evidence

Current HL7 FHIR/fhir-test-cases JSON resource validation status:

  • Upstream manifest entries: 969 at pinned commit 8923095fc5e3750025f7dd71988c9e89083b1487.
  • Pre-filtered out before validation: 433, including one entry without a declared java baseline: (default)/zzz, an upstream platform-specific teardown workaround rather than a validator comparison case.
  • Candidate JSON comparison set: 536 entries with a declared java baseline.
  • Runtime skipped from the headline lane: 0.
  • Executed and compared against Java OperationOutcome: 536.
  • 536 passed; no executable parity differences remain.
  • Headline JSON resource parity: 100.0%.

Reproduce the headline lane locally with:

npm run conformance -- --tx-server none --output-file conformance-results/report-local.json

Current and scoped evidence artifacts:

The 433 pre-filtered entries are not counted as failures because they do not exercise the thing this harness measures: JSON FHIR resource validation with a Java OperationOutcome baseline. They include XML resources, older FHIR versions, unsupported modules (SHC, CDA, CDS Hooks, JSON5, XVer, DSIG, HL7 v2), disabled upstream tests, logical models, or entries without a declared Java baseline.

The upstream manifest now supplies resolvable Java outcomes for every headline candidate, and all 536 executable comparisons match the normalized Java result. The historical --include-baseline-backlog artifact is retained for provenance but is not the current headline measurement.

The scope expansion plan is tracked in docs/conformance-scope-roadmap.md.

Why So Many Manifest Entries Are Not Counted

The HL7 manifest is broader than "validate one FHIR JSON resource and compare the validator output." It also contains test assets for other formats, protocols, historical versions, and adjacent standards. Counting those as validator failures would make the metric less honest: it would mix unsupported product scope with actual JSON resource validation correctness.

Excluded class Why it is not part of this score What would be needed to include it
XML resources The package currently validates parsed JSON resources. XML requires parsing, XML-specific diagnostics, and stable XML-to-resource location mapping. Add an XML parser/normalizer and an XML-aware diagnostic mapper, then run XML fixtures as a separate conformance lane.
CDA, HL7 v2, CDS Hooks, SHC, DSIG, JSON5, XVer These are adjacent standards or special harnesses, not plain FHIR JSON resource validation. Some are transformation/signature/protocol tests rather than resource validation tests. Build dedicated modules and dedicated conformance harnesses for each format/protocol.
Older FHIR versions (3.0, 3.0.1, 1.4) The validator package targets R4, R5, and R6. Legacy STU3/DSTU-era behavior differs enough that it should not be silently mixed into the R4 score. Add explicit legacy-version support and report it as a separate compatibility score.
Upstream-disabled tests The upstream manifest marks them with use-test: false, so the reference suite itself does not treat them as active comparison cases. Re-enable only if upstream enables them or if this project defines its own expected baseline.
Logical model tests Logical models are not ordinary FHIR resource-instance validation cases. Add logical-model validation support and a separate result category.
Missing Java baselines The comparison metric is Java parity. Without an expected Java OperationOutcome, there is no objective diff target. Generate and commit Java baselines, or define a Records-owned expected baseline with a different metric name.
.fml / .ndjson payloads They pass the manifest filter but are not single JSON resource documents. Add FML/NDJSON-specific loaders and compare them in dedicated lanes.

For that reason, the headline number should be read as:

Records matches the Java validator on all 536 currently in-scope FHIR JSON resource validation comparisons.

It should not be read as:

Records implements every format, protocol, legacy version, and adjacent standard represented somewhere in the upstream manifest.

Spec dispatch coverage for the measured R4 base package constraints is 100%.

MII 2026 Reference Scope

MII conformance is measured in a separate lane from the HL7 FHIR/fhir-test-cases score. The current scoped MII-2026 reference run was generated on 2026-07-23 against the official MII FHIR Validator container mii-fhir-validator:0.0.1-alpha.7. It matches the reference validator on 231/231 measured resources from the refreshed MII 2026 corpus under the mii-2026-reference profile scope and mii-local-blaze terminology mode, with 22 classified skips: 12 corpus/profile-drift skips and 10 reference-terminology-incomplete skips. The run prewarmed 128/128 reference-scope profiles before executing the cases. The source-repository report is conformance-results/mii-triangulation-2026-07-23.json.

This is a scoped parity claim for the measured package-example corpus. It is not an MII certification claim and does not imply full site-level MII Must-Support readiness.

FHIR Schema Dual-Path Scope

FHIR Schema is being evaluated as a cleaner intermediate representation for the same StructureDefinition semantics, not as a replacement for conformance evidence. The current engine remains StructureDefinition-first. The FHIR Schema graph path runs in parallel and is compared against both the current StructureDefinition path and Java/reference OperationOutcome evidence where a reference report exists.

The current all-scope MII dual-path lane covers 555 real fixtures. Of those, 512 have Java/reference coverage through the attached Java CLI supplement conformance-results/fhir-schema-reference-cli-supplement-all-2026-07-01.json. The final report is conformance-results/fhir-schema-dual-path-all-2026-07-23.json.

The lane reports 418 clean cases, 71 exact Graph/Records comparable matches, 11 graph-only cases, 0 Records-only cases, 0 divergent cases, 55 missing-profile cases, and 0 execution errors. Twelve normalized issue-key gaps across the 11 graph-only cases are explicitly deferred because their reference-slice discriminators require external targets unavailable to the standalone fixture; Records reports those slices as unverifiable instead of declaring the resources invalid. No other Java-confirmed runtime gap remains. This lane is an implementation-reduction and convergence signal; it does not broaden the public headline parity claim beyond the explicitly measured FHIR JSON comparison lanes.

Examples

The package-level README contains the fuller API guide: packages/validator/README.md.

Development

npm install
npm run typecheck
npm run build
npm run oss:audit-validator
npm run oss:smoke-validator

Publishing Order

  1. Publish @records-fhir/validation-types.
  2. Publish @records-fhir/validator.
  3. Publish @records-fhir/bundled-profiles only after third-party license review.

License

Apache-2.0 for the validator packages unless a package-level notice states otherwise. Bundled third-party FHIR artifacts retain their upstream licenses and notices.

FHIR Validator is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support documentation.

About

Validate FHIR R4/R4B/R5/R6 JSON resources with the Records TypeScript validator
validator-v0.5.0
Latest

FHIR Validator is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support documentation.