Skip to content

Bundle recipes

The default generate bundle command composes a realistic Bundle for you. When a pipeline test needs a specific Bundle shape — a fixed resource mix, particular codes and values, and a known reference graph — define a recipe instead.

Recipes are composition rules, not clinical scenario models. You choose the resources, codes, values, and reference wiring; fhir-test-data handles deterministic generation, the FHIR resource builders, deep-merged field overrides, and reference resolution.

Terminal window
fhir-test-data generate bundle --recipe ./lab-result-basic.yaml --seed 42

A recipe is a YAML or JSON document with a name, optional defaults, and an ordered list of resources. Later resources can reference earlier ones by their id alias.

name: lab-result-basic
locale: uk
fhirVersion: R4
bundle:
type: transaction
resources:
- type: Patient
id: patient
- type: Encounter
id: encounter
fields:
subject: patient
- type: Observation
id: hba1c
fields:
subject: patient
encounter: encounter
category:
- coding:
- system: http://terminology.hl7.org/CodeSystem/observation-category
code: laboratory
display: Laboratory
code:
coding:
- system: http://loinc.org
code: "4548-4"
display: HbA1c
valueQuantity:
value: 7.2
unit: "%"
system: http://unitsofmeasure.org
code: "%"
- type: DiagnosticReport
id: report
fields:
subject: patient
encounter: encounter
code:
coding:
- system: http://loinc.org
code: "55454-3"
display: Hemoglobin A1c in Blood
result:
- hba1c
FieldRequiredDescription
nameyesHuman-readable recipe name, used in diagnostics.
localenoDefault locale for identifiers, names, and addresses. Overridden by --locale.
fhirVersionnoDefault FHIR version (R4 | R4B | R5). Overridden by --fhir-version. Default R4.
bundle.typenoBundle type (transaction, collection, searchset, …). Default transaction.
resourcesyesOrdered, non-empty list of resource entries.
FieldRequiredDescription
typeyesResource type to generate: Patient, Practitioner, PractitionerRole, Organization, Observation, Condition, AllergyIntolerance, MedicationStatement, Encounter, DiagnosticReport.
idyesAlias other entries use to reference this resource. Must be unique.
countnoNumber of resources to generate for this entry. Cannot be combined with a fields.id override.
fieldsnoObject deep-merged into the generated resource after builder defaults.

Reference fields resolve recipe aliases to the generated resource’s urn:uuid: reference automatically. Supported reference fields include subject, encounter, performer, result, organization, and practitioner.

In the example above, Observation.subject: patient becomes a reference to the generated Patient, and DiagnosticReport.result: [hba1c] becomes a reference to the generated Observation. An unknown alias, or an alias that resolves to multiple resources, is a recipe error.

Any non-reference fields value is deep-merged into the generated resource, so you can pin exact codes, categories, and values while letting the builder fill in the rest.

CLI flags win over recipe defaults, so one recipe can drive multiple locales and versions:

Terminal window
fhir-test-data generate bundle --recipe ./lab-result-basic.yaml \
--locale us --fhir-version R5 --count 2 --seed 42

With a fixed --seed, the same recipe produces byte-identical Bundles across runs and machines — suitable for committing as regression fixtures.

Ready-to-use recipes ship with the package under examples/recipes/:

  • lab-result-basic.yaml — Patient, Encounter, Observation, DiagnosticReport.
  • condition-medication-basic.yaml — Patient, Condition, MedicationStatement.
  • diagnostic-workup-basic.yaml — Patient, Practitioner, Organization, Encounter, Observation, DiagnosticReport.

The same behavior is available programmatically via createBundleFromRecipe:

import { createBundleFromRecipe, type BundleRecipe } from "fhir-test-data";
const recipe: BundleRecipe = {
name: "lab-result-basic",
locale: "uk",
fhirVersion: "R4",
bundle: { type: "transaction" },
resources: [
{ type: "Patient", id: "patient" },
{ type: "Observation", id: "hba1c", fields: { subject: "patient" } },
],
};
// Returns an array of Bundles (one per `count`, default 1).
const [bundle] = createBundleFromRecipe(recipe, { seed: 42 });

createBundleFromRecipe(recipe, options) accepts seed, locale, fhirVersion, and count in options, each overriding the recipe’s defaults. Invalid recipes throw a BundleRecipeError with a message pointing at the offending field.