<div align="center">
  <img src="./logo_transparent.png" alt="BabelFHIR-TS Logo" width="200"/>
</div>

# BabelFHIR-TS

<p align="center">
  <strong>Generate production-ready TypeScript from FHIR® StructureDefinitions — typed interfaces, runtime validators, and FHIR clients.</strong>
</p>

<!-- Version & Spec Badges -->
<p align="center">
  <a href="https://www.npmjs.com/package/babelfhir-ts"><img src="https://img.shields.io/npm/v/babelfhir-ts.svg?label=babelfhir-ts" alt="npm"></a>
  <a href="https://hl7.org/fhir/R4/"><img src="https://img.shields.io/badge/FHIR-R4%20%7C%20R4B%20%7C%20R5-orange.svg" alt="FHIR R4/R4B/R5"></a>
  <a href="https://opensource.org/licenses/ISC"><img src="https://img.shields.io/badge/License-ISC-blue.svg" alt="License: ISC"></a>
</p>

<!-- Tech Stack Badges -->
<p align="center">
  <img src="https://img.shields.io/badge/TypeScript-6.0-3178c6?logo=typescript" alt="TypeScript">
  <img src="https://img.shields.io/badge/Node.js-18%2B-339933?logo=node.js" alt="Node.js">
  <img src="https://img.shields.io/badge/Zod-4.x-3068b7?logo=zod" alt="Zod">
</p>

<!-- FHIR Client Packages -->
<p align="center">
  <a href="https://www.npmjs.com/package/@babelfhir-ts/client-r4"><img src="https://img.shields.io/npm/v/@babelfhir-ts/client-r4.svg?label=%40babelfhir-ts%2Fclient-r4" alt="client-r4"></a>
  <a href="https://www.npmjs.com/package/@babelfhir-ts/client-r4b"><img src="https://img.shields.io/npm/v/@babelfhir-ts/client-r4b.svg?label=%40babelfhir-ts%2Fclient-r4b" alt="client-r4b"></a>
  <a href="https://www.npmjs.com/package/@babelfhir-ts/client-r5"><img src="https://img.shields.io/npm/v/@babelfhir-ts/client-r5.svg?label=%40babelfhir-ts%2Fclient-r5" alt="client-r5"></a>
  <a href="https://www.npmjs.com/package/@babelfhir-ts/smart-auth"><img src="https://img.shields.io/npm/v/@babelfhir-ts/smart-auth.svg?label=%40babelfhir-ts%2Fsmart-auth" alt="smart-auth"></a>
</p>

<!-- Validation & Imaging Packages -->
<p align="center">
  <a href="https://www.npmjs.com/package/@babelfhir-ts/zod"><img src="https://img.shields.io/npm/v/@babelfhir-ts/zod.svg?label=%40babelfhir-ts%2Fzod" alt="zod"></a>
  <a href="https://www.npmjs.com/package/@babelfhir-ts/dicomweb"><img src="https://img.shields.io/npm/v/@babelfhir-ts/dicomweb.svg?label=%40babelfhir-ts%2Fdicomweb" alt="dicomweb"></a>
</p>

**BabelFHIR-TS** transforms FHIR® StructureDefinitions into production-ready TypeScript code with full type safety and built-in validation. BabelFHIR-TS generates **profile-aware** interfaces that understand your Implementation Guide's constraints, extensions, and slicing rules.

### What you get

- **Strongly typed interfaces** that merge profile constraints with base FHIR types (types come from `@types/fhir`)
- **Compiled output by default** — packages ship JavaScript (`.js`) plus TypeScript declarations (`.d.ts`)
- **Runtime validation** using FHIRPath expressions from the profile—no external validator required for basic checks
- **Type-safe extension handling** with proper slicing and nested extension support
- **Random data builders** for testing and development (when class generation is enabled)
- **Zero manual mapping**—consume any FHIR package or Implementation Guide directly from registries
- **Fast and lightweight**—the CLI pulls no FHIRPath engine of its own; generated packages declare `fhirpath` as a *peer* dependency (`>=5.2.0 <6`), so the host app owns the version
- **Type-safe FHIR client** — generated client extends [`@babelfhir-ts/client-r4`](https://www.npmjs.com/package/@babelfhir-ts/client-r4) / [`client-r4b`](https://www.npmjs.com/package/@babelfhir-ts/client-r4b) / [`client-r5`](https://www.npmjs.com/package/@babelfhir-ts/client-r5) with profile-specific methods (e.g., `.uSCorePatientProfile()`, `.pASClaim()`) on top of base resource accessors
- **Install any FHIR profile as a node module**—use `babelfhir-ts install` to add Implementation Guides (FHIR Packages) directly to your project

## Installation

```bash
npm install -g babelfhir-ts
```

Or on-demand: `npx babelfhir-ts --help`

> **Requirements:** Node.js 18+ and an internet connection for remote registries.

## Quick Start

```bash
# Generate from a local folder
babelfhir-ts input/ output/

# Download and process from a registry
babelfhir-ts --package hl7.fhir.us.core@8.0.0

# Install as a project dependency
babelfhir-ts install hl7.fhir.us.core@8.0.0
```

```ts
import { USCorePatientProfileClass } from "./output/USCorePatientProfileClass";

const patient = USCorePatientProfileClass.random();
const { errors, warnings } = await patient.validate();
```

## CLI Reference

<!-- CLI_HELP_START -->
```
BabelFHIR-TS: Generate TypeScript interfaces from FHIR StructureDefinitions

Usage:
  babelfhir-ts [options] [<input> [output]]
  babelfhir-ts install [--package] <pkg[@version]|path> [--registry <url>] [options]
  babelfhir-ts update [<pkg@version>] [--recursive] [options]

Arguments:
  input   Input can be:
          - Canonical URL of a FHIR profile (http://... or https://...)
          - Directory containing FHIR packages (.tgz/.zip files)
          - Single FHIR package (.tgz/.zip file)
          - Single StructureDefinition (.json file)
          - Directory containing StructureDefinition files
  output  Output directory or archive name (optional)

Commands:
  install                Download, process, and npm install package as dependency
  update                 Regenerate all installed packages (or a specific one) with current babelfhir-ts

Options:
  -h, --help               Show this help message
  -v, --version            Show version number
  --log <dest>             Log destination: console (default) or file
  --log-level <level>      Log verbosity: error, warn, info (default), or debug
  --cache-dir <path>       Custom cache directory (default: ~/.fhir/packages for FHIR packages, .cache for working files)
  --no-cache               Delete .cache working folder after generation (does not affect shared ~/.fhir/packages)
  --no-classes             Only generate interfaces and types (skip class generation)
  --no-client              Skip FHIR client generation (client generated by default)
  --schema <format>        Generate schema files alongside outputs (supported: zod)
  --zod-invariants         Emit FHIRPath invariants into Zod schemas (fuller checking, slower parse)
  --dicomweb               Generate DICOMweb helpers typed to ImagingStudy profiles in the IG
  --prefab                 Generate Prefab UI render functions per profile (@maxhealth.tech/prefab)
  --prefab-styles <path>   Path to styles module (.ts/.js) copied into the generated prefab/ folder
  --recursive              (update only) Recursively search subdirectories for lib/ folders
  --force                  (update only) Force regeneration even if version and flags haven't changed
  --skip-install           (install only) Generate tarball without running package manager install
  --outDir <dir>           Output directory (alias for second positional argument)
  --fhir-version <ver>     FHIR version to target: r4, r4b, or r5 (auto-detected from package if omitted)
  --package <pkg[@version]>  Download FHIR package from registry and process it (latest if no version)
  --registry <url>         FHIR package registry URL (default: https://packages.simplifier.net)
  --tx-server <url>        Terminology server URL for ValueSet expansion (e.g., https://tx.fhir.org/r4)
                           When set, expands ValueSets without explicit codes using $expand operation
  --display-language <lang> BCP-47 language(s) for display terms (e.g., de or de,fr,en).
                           Single value replaces concept displays. Comma-separated values
                           also generate a multi-language display map with getDisplay() helper.

Examples:
  babelfhir-ts                                             # Process ./input to ./output
  babelfhir-ts http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient  # Generate from profile URL
  babelfhir-ts package.tgz                                 # Process package to current directory
  babelfhir-ts package.tgz modified-package.tgz            # Embed interfaces in package
  babelfhir-ts profiles/ generated/                        # Process directory to directory
  babelfhir-ts --package hl7.fhir.us.core@8.0.0            # Download and process from default registry
  babelfhir-ts --package hl7.fhir.us.core@8.0.0 output/    # Download and output to directory
  babelfhir-ts --package pkg@version --log console --log-level debug  # With verbose logging
  babelfhir-ts install de.gematik.isik-basismodul                           # Download latest, process, and install
  babelfhir-ts install de.gematik.isik-basismodul@3.1.0                   # Download specific version
  babelfhir-ts install ./package.tgz                                      # Install from local package file
  babelfhir-ts install hl7.fhir.us.core@8.0.0 --registry <url>            # Install from custom registry
  babelfhir-ts install --package hl7.fhir.us.core@8.0.0 --registry <url>  # Alternative syntax
  babelfhir-ts update                                                      # Regenerate all packages in ./lib
  babelfhir-ts update hl7.fhir.us.core@8.0.0                               # Regenerate a specific package
  babelfhir-ts update --recursive                                          # Regenerate packages in all subdirectories
```
<!-- CLI_HELP_END -->

## Documentation

Full documentation is available at **[max-health-inc.github.io/BabelFHIR-TS/docs/](https://max-health-inc.github.io/BabelFHIR-TS/docs/)**

- [Getting Started](https://max-health-inc.github.io/BabelFHIR-TS/docs/getting-started) — installation, quick start, first generation
- [CLI Reference](https://max-health-inc.github.io/BabelFHIR-TS/docs/cli-reference) — full list of commands and options
- [Generated Code Guide](https://max-health-inc.github.io/BabelFHIR-TS/docs/generated-code) — understanding the output, module resolution, FHIR type imports
- [FHIR Client](https://max-health-inc.github.io/BabelFHIR-TS/docs/fhir-client) — type-safe server interactions
- [Validation](https://max-health-inc.github.io/BabelFHIR-TS/docs/validation) — what validators check, CI pipelines, known Firely SDK issues
- [Limitations](https://max-health-inc.github.io/BabelFHIR-TS/docs/limitations) — edge cases, random() caveats
- [Contributing](https://max-health-inc.github.io/BabelFHIR-TS/docs/contributing) — dev setup, scripts, project structure

<!-- PARITY-BADGES:START - Do not remove or modify this section -->
## Continuous Validation

Every push to `develop` and `main` runs the parity pipeline, which validates generated code against real-world FHIR Implementation Guides. (Pull requests run the faster `CI` workflow: typecheck, unit tests, and generated-artifact drift checks.) For each IG, the pipeline:

1. Downloads the FHIR package from a registry
2. Generates TypeScript interfaces, validators, and classes
3. Compiles the output with `tsc` (zero errors required)
4. Generates `empty()` and `random()` test resources for every profile
5. Validates those resources against two independent external FHIR validators

### Validated Implementation Guides (31)

Every parity run validates **31 real-world IGs** (29 R4, 2 R5). The list is not duplicated here — it is generated from the parity suite's own source of truth into [`parity-matrix.json`](./parity-matrix.json).

Each validated IG is also published as a ready-to-install package — `@max-health-inc/fhir-<name>` — so you do not have to generate it yourself:

**[→ Browse the FHIR IG registry](https://github.com/orgs/Max-Health-Inc/packages?ecosystem=npm&q=fhir-)**

```bash
# GitHub Packages needs the scope mapped, and a token with read:packages
echo "@max-health-inc:registry=https://npm.pkg.github.com" >> .npmrc
npm install @max-health-inc/fhir-us-core
```

Published by [Max-Health-Inc/fhir-igs](https://github.com/Max-Health-Inc/fhir-igs), which pins a babelfhir-ts version and republishes an IG only when the IG version, the pinned generator, or the generation flags actually change.

### Validation with the Firely SDK Validator

The `firely` job validates generated resources using the [Firely SDK Validator](https://docs.fire.ly/projects/Firely-NET-SDK/validation.html) (`Firely.Fhir.Validation`, v3.x) running on the Firely .NET SDK (`Hl7.Fhir`, v6.x) — two separately versioned packages. Results are published as live badges:

<details><summary>Per-IG results</summary>

![US Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-us-core.json)
![QI-Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-qicore.json)
![mCODE](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-mcode.json)
![SDOH Clinical Care](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-sdoh.json)
![NDH (National Directory)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-ndh.json)
![CARIN BB](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-carin-bb.json)
![CQF Measures](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-cqfmeasures.json)
![Physical Activity](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-physical-activity.json)
![DaVinci PAS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-pas.json)
![DaVinci CDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-cdex.json)
![DaVinci PDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-pdex.json)
![DaVinci DTR](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-dtr.json)
![DaVinci Alerts](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-alerts.json)
![DaVinci DEQM](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-deqm.json)
![DaVinci Drug Formulary](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-drug-formulary.json)
![IPS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-ips.json)
![SMART App Launch](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-smart.json)
![SDC (Structured Data Capture)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-sdc.json)
![Genomics Reporting](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-genomics-reporting.json)
![CPG (Clinical Practice Guidelines)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-cpg.json)
![ISiK Basis](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-isik-basis.json)
![KBV eRezept](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-kbv-erp.json)
![DE Basisprofil](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-de-basisprofil.json)
![ISiK Medikation](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-isik-medikation.json)
![CH Core (Switzerland)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-ch-core.json)
![AU Core (Australia)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-au-core.json)
![PIXm](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-pixm.json)
![MHD](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-mhd.json)
![vitals](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-vitals.json)

</details>

### Validation with HL7 Java Validator

The `hl7` job validates the same artifacts using the [official HL7 FHIR Validator](https://confluence.hl7.org/display/FHIR/Using+the+FHIR+Validator), the reference implementation for FHIR conformance checking:

<details><summary>Per-IG results</summary>

![US Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-us-core.json)
![QI-Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-qicore.json)
![mCODE](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-mcode.json)
![SDOH Clinical Care](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-sdoh.json)
![NDH (National Directory)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-ndh.json)
![CARIN BB](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-carin-bb.json)
![CQF Measures](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-cqfmeasures.json)
![Physical Activity](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-physical-activity.json)
![DaVinci PAS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-pas.json)
![DaVinci CDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-cdex.json)
![DaVinci PDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-pdex.json)
![DaVinci DTR](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-dtr.json)
![DaVinci Alerts](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-alerts.json)
![DaVinci DEQM](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-deqm.json)
![DaVinci Drug Formulary](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-drug-formulary.json)
![IPS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-ips.json)
![SMART App Launch](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-smart.json)
![SDC (Structured Data Capture)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-sdc.json)
![Genomics Reporting](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-genomics-reporting.json)
![CPG (Clinical Practice Guidelines)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-cpg.json)
![ISiK Basis](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-isik-basis.json)
![KBV eRezept](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-kbv-erp.json)
![DE Basisprofil](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-de-basisprofil.json)
![ISiK Medikation](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-isik-medikation.json)
![CH Core (Switzerland)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-ch-core.json)
![AU Core (Australia)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-au-core.json)
![PIXm](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-pixm.json)
![MHD](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-mhd.json)
![vitals](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-vitals.json)

</details>

> External-validator badges cover the 29 R4/R4B IGs. R5 packages are generated and typechecked, but neither external validator publishes R5 badges yet.

> Terminology validation requires a tx server. The pipeline uses `--tx-server https://tx.fhir.org/{r4|r5}` (matching the package's FHIR version) during generation to expand ValueSets and produce valid codes.

📊 **[Full Report](https://max-health-inc.github.io/BabelFHIR-TS/)**
<!-- HL7-PARITY-BADGES:END -->
<!-- PARITY-BADGES:END -->

## License

ISC © Maximilian Nussbaumer

## Changelog

Release notes are published automatically on GitHub Releases:
**[View all releases](https://github.com/Max-Health-Inc/BabelFHIR-TS/releases)**

## Contributing

Contributions are welcome! See the [Contributing guide](https://max-health-inc.github.io/BabelFHIR-TS/docs/contributing) for dev setup, scripts, and how to submit changes.

## Security

For security issues, please see [SECURITY.md](SECURITY.md) for our security policy and how to report vulnerabilities.

## Links

- [npm package — babelfhir-ts](https://www.npmjs.com/package/babelfhir-ts)
- [npm package — @babelfhir-ts/client-r4](https://www.npmjs.com/package/@babelfhir-ts/client-r4) / [client-r4b](https://www.npmjs.com/package/@babelfhir-ts/client-r4b) / [client-r5](https://www.npmjs.com/package/@babelfhir-ts/client-r5)
- [npm package — @babelfhir-ts/zod](https://www.npmjs.com/package/@babelfhir-ts/zod)
- [GitHub repository](https://github.com/Max-Health-Inc/BabelFHIR-TS)
- [Validation report](https://max-health-inc.github.io/BabelFHIR-TS/)
- [Issue tracker](https://github.com/Max-Health-Inc/BabelFHIR-TS/issues)
- [Changelog / Releases](https://github.com/Max-Health-Inc/BabelFHIR-TS/releases)
