Quick Start
Get from zero to a type-safe FHIR query in three steps.
Step 1: Generate Types
Run the CLI to generate TypeScript types from the FHIR R4 specification:
npx @fhir-dsl/cli generate --version r4 --out ./src/fhir
This downloads the official FHIR R4 StructureDefinitions and generates typed interfaces for every resource, search parameter, and include relationship.
The generated output looks like this:
src/fhir/
r4/
index.ts # Schema type + createClient helper
resources/
patient.ts # Patient interface
observation.ts # Observation interface
... # One file per resource
search-params.ts # Typed search parameters
registry.ts # Type registries
client.ts # Pre-typed createClient()
With Implementation Guide Profiles
To include US Core (or any IG) profiles:
npx @fhir-dsl/cli generate \
--version r4 \
--ig hl7.fhir.us.core@6.1.0 \
--out ./src/fhir
This adds a profiles/ directory with narrowed types for each profile.
Generate Only Specific Resources
If you only need a subset of resources:
npx @fhir-dsl/cli generate \
--version r4 \
--resources Patient,Observation,Encounter \
--out ./src/fhir
Step 2: Create a Client
Use the generated createClient helper for a fully typed client:
import { createClient } from "./fhir/r4";
const fhir = createClient({
baseUrl: "https://hapi.fhir.org/baseR4",
});
Or if you need authentication:
const fhir = createClient({
baseUrl: "https://your-fhir-server.com/fhir",
auth: {
type: "bearer",
credentials: "your-access-token",
},
});
Step 3: Query With Type Safety
Search for Resources
const result = await fhir
.search("Patient")
.where("family", "eq", "Smith")
.where("birthdate", "ge", "1990-01-01")
.sort("birthdate", "desc")
.count(10)
.execute();
// result.data is Patient[]
for (const patient of result.data) {
console.log(patient.name?.[0]?.family);
console.log(patient.birthDate);
}
Every argument is type-checked:
"Patient"must be a valid resource type"family"must be a valid search parameter for Patient"eq"must be a valid operator for string parameters- The value type is validated against the parameter type
Read a Single Resource
const patient = await fhir.read("Patient", "123").execute();
// patient is typed as Patient
Build Transactions
const bundle = await fhir
.transaction()
.create({
resourceType: "Patient",
name: [{ family: "Doe", given: ["Jane"] }],
gender: "female",
})
.execute();
Compile Without Executing
Inspect the raw query without sending it:
const query = fhir
.search("Observation")
.where("status", "eq", "final")
.count(50)
.compile();
console.log(query);
// {
// method: "GET",
// path: "Observation",
// params: [
// { name: "status", value: "final" },
// { name: "_count", value: 50 }
// ]
// }
tip
compile() is useful for debugging, logging, or when you want to execute the query with a custom HTTP client.
What's Next?
- Learn about Core Concepts to understand the type system
- See more Examples for real-world patterns
- Set up the CLI for your project