Skip to main content

Installation

Requirements

  • Node.js >= 20
  • TypeScript >= 5.0 with strict: true
  • A package manager: npm, pnpm, or yarn

Required packages

Every project needs the query builder (@fhir-dsl/core) and the HTTP executor (@fhir-dsl/runtime). @fhir-dsl/types is installed transitively.

# npm
npm install @fhir-dsl/core @fhir-dsl/runtime

# pnpm
pnpm add @fhir-dsl/core @fhir-dsl/runtime

# yarn
yarn add @fhir-dsl/core @fhir-dsl/runtime

Optional packages

Add only what you use.

PackageInstallUse when
@fhir-dsl/clidev depGenerating types during build / CI. Shipped as a binary named fhir-gen.
@fhir-dsl/fhirpathruntime depWriting type-safe FHIRPath expressions (fhirpath<Patient>("Patient").name.family.compile()).
@fhir-dsl/smartruntime depSMART on FHIR v2 (authorize + PKCE S256, Backend Services JWT, SmartClient).
@fhir-dsl/terminologyruntime depParsing / resolving CodeSystems and ValueSets in-process.
# Dev-only: the generator CLI
npm install -D @fhir-dsl/cli

# Runtime: whichever of these you need
npm install @fhir-dsl/fhirpath @fhir-dsl/smart @fhir-dsl/terminology

Run the generator

The CLI downloads the FHIR spec (and any IGs) and writes a typed client into your repo. Convention throughout these docs: output goes to ./src/fhir and the generated client is imported from ./fhir/r4.

npx @fhir-dsl/cli generate \
--version r4 \
--ig hl7.fhir.us.core@6.1.0 \
--out ./src/fhir

All generator flags

Every flag below is exposed by packages/cli/src/commands/generate.ts.

FlagValuePurpose
--version <v>r4 | r4b | r5 | r6FHIR base spec to download. Required.
--out <dir>pathOutput directory for generated types. Required.
--ig <pkg...>name@ver or name#ver, repeatableIG packages to layer on top of the base spec. Later wins on conflicts.
--resources <list>Patient,Observation,...Comma-separated allowlist. Default: all resources.
--src <path>pathUse a local spec directory instead of downloading. Handy for air-gapped CI.
--cache <dir>pathCache directory for downloaded spec + IG tarballs.
--expand-valuesetsflagInline ValueSet expansions into narrowed Coding<T> / CodeableConcept<T> unions.
--resolve-codesystemsflagEmit CodeSystem namespace objects for IntelliSense.
--include-specflagCopy the raw StructureDefinition JSON next to generated types (LLM / AI context).
--validator <t>zod | nativeEmit Standard Schema v1 validators. native has zero runtime deps.
--strict-extensibleflagTreat extensible bindings as closed unions (validators only).

Full example using every flag:

npx @fhir-dsl/cli generate \
--version r4 \
--out ./src/fhir \
--ig hl7.fhir.us.core@6.1.0 \
--ig hl7.fhir.uv.ips@1.1.0 \
--resources Patient,Observation,Encounter \
--src ./vendor/fhir-spec \
--cache ./.fhir-cache \
--expand-valuesets \
--resolve-codesystems \
--include-spec \
--validator zod \
--strict-extensible

TypeScript configuration

strict: true is required — optional chaining, profile narrowing, and the search-param discriminator all rely on it.

{
"compilerOptions": {
"strict": true,
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler"
}
}

Next steps

Head to the Quick Start to run your first typed query.