{"id":50218559,"url":"https://github.com/alysivji/fhir-zod","last_synced_at":"2026-05-26T10:35:12.936Z","repository":{"id":351470139,"uuid":"1194133888","full_name":"alysivji/fhir-zod","owner":"alysivji","description":"Type-safe FHIR models and runtime validation with Zod","archived":false,"fork":false,"pushed_at":"2026-04-28T02:53:55.000Z","size":11186,"stargazers_count":1,"open_issues_count":6,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T05:13:37.925Z","etag":null,"topics":["fhir","fhir-r4","fhir-r4b","fhir-r5","fhir-stu3","healthcare","hl7","hl7-fhir","typescript","validation","zod","zod-validation"],"latest_commit_sha":null,"homepage":"https://fhir-zod.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alysivji.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-28T00:46:50.000Z","updated_at":"2026-04-28T02:50:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/alysivji/fhir-zod","commit_stats":null,"previous_names":["alysivji/fhir-zod"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/alysivji/fhir-zod","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alysivji%2Ffhir-zod","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alysivji%2Ffhir-zod/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alysivji%2Ffhir-zod/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alysivji%2Ffhir-zod/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alysivji","download_url":"https://codeload.github.com/alysivji/fhir-zod/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alysivji%2Ffhir-zod/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33517117,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T03:12:49.672Z","status":"ssl_error","status_checked_at":"2026-05-26T03:12:47.976Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fhir","fhir-r4","fhir-r4b","fhir-r5","fhir-stu3","healthcare","hl7","hl7-fhir","typescript","validation","zod","zod-validation"],"created_at":"2026-05-26T10:35:12.037Z","updated_at":"2026-05-26T10:35:12.932Z","avatar_url":"https://github.com/alysivji.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fhir-zod\n\nFHIR types and Zod validation for TypeScript — install, import, validate. No generators, no servers, no HL7 toolchain required.\n\n![FHIR R5](https://img.shields.io/badge/FHIR-R5-purple) ![FHIR R4B](https://img.shields.io/badge/FHIR-R4B-blue) ![FHIR R4](https://img.shields.io/badge/FHIR-R4-green) ![FHIR STU3](https://img.shields.io/badge/FHIR-STU3-lightgrey)\n\n[![npm version](https://img.shields.io/npm/v/fhir-zod.svg)](https://www.npmjs.com/package/fhir-zod) ![Zod](https://img.shields.io/badge/Zod-3.25.x%20%7C%204.x.x-3068B7?logo=zod\u0026logoColor=white) [![CI](https://github.com/alysivji/fhir-zod/actions/workflows/ci.yml/badge.svg)](https://github.com/alysivji/fhir-zod/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/alysivji/fhir-zod/graph/badge.svg)](https://codecov.io/gh/alysivji/fhir-zod)\n\n## Why use it?\n\n- 📦 **Works out of the box**: pre-generated TypeScript models and Zod schemas from pinned HL7 definitions. No spec files to download, no generators to run.\n- ⚡ **Validate without a server**: in-process Zod validation — no validation server, no network round-trips, no infrastructure.\n- 🗂️ **One library, every major FHIR version**: R5, R4B, R4, and STU3 with explicit versioned entry points.\n- 🌳 **Tree-shakeable**: unused FHIR versions are excluded from your bundle. See [Bundle size and imports](#bundle-size-and-imports) for how polymorphic fields affect bundling.\n- 🧪 **Validated against official examples**: schemas are tested against HL7's own example fixtures for each supported version.\n- ✅ **Zod 3 and 4**: fits into existing Zod-based validation workflows without swapping validation stacks.\n\n## Installation\n\n```bash\nnpm install fhir-zod zod\n```\n\nCompatible with [Zod](https://zod.dev/) `^3.25.1` and `^4.0.0`.\n\nSupports Node.js 20+ and modern bundlers. Import concrete resources from resource module entry points such as `fhir-zod/r4/Patient`. Versioned entry points such as `fhir-zod/r4` expose shared datatypes and supporting generated definitions.\n\n## Documentation\n\nBrowse the package docs at \u003chttps://fhir-zod.vercel.app/\u003e.\n\nThe VitePress source for package usage and validation boundaries lives in [`docs/`](./docs/). Preview it locally with:\n\n```bash\nnpm run docs:dev\n```\n\n## Quick start\n\n```ts\nimport { PatientSchema, type Patient } from \"fhir-zod/r4/Patient\"\n\nconst patient: Patient = {\n  resourceType: \"Patient\",\n  id: \"john-doe\",\n  active: true,\n  name: [{ family: \"Doe\", given: [\"John\"] }],\n  gender: \"male\",\n  birthDate: \"1985-03-15\",\n}\n\nconst result = PatientSchema.safeParse(patient)\n\nif (!result.success) {\n  console.error(result.error.issues)\n}\n```\n\nUse the TypeScript model when you want the FHIR shape in code, and use the schema when data crosses a trust boundary.\n\nThe versioned entrypoints import from bare `zod`, so their schema instances follow the installed Zod package. `fhir-zod` works with the same generated schema surface across Zod `^3.25.1` and `^4.0.0`:\n\n```ts\nimport { PatientSchema } from \"fhir-zod/r4/Patient\"\n```\n\n## Common use cases\n\n### Validate data from an API\n\n```ts\nimport { PatientSchema } from \"fhir-zod/r4/Patient\"\n\nconst response = await fetch(\"/api/patient/john-doe\")\nconst payload: unknown = await response.json()\n\nconst parsed = PatientSchema.safeParse(payload)\n\nif (!parsed.success) {\n  throw new Error(\"Received an invalid R4 Patient payload\")\n}\n\nconsole.log(parsed.data.resourceType)\n```\n\n### Validate choice fields\n\nFHIR choice fields such as `value[x]` are emitted as concrete fields such as `valueQuantity`, `valueString`, and `valueBoolean`. The generated schemas reject payloads that provide more than one value for the same choice group.\n\n```ts\nimport { ObservationSchema, type Observation } from \"fhir-zod/r4/Observation\"\n\nconst bodyWeight: Observation = {\n  resourceType: \"Observation\",\n  status: \"final\",\n  code: {\n    coding: [\n      {\n        system: \"http://loinc.org\",\n        code: \"29463-7\",\n        display: \"Body weight\",\n      },\n    ],\n  },\n  subject: { reference: \"Patient/john-doe\" },\n  valueQuantity: {\n    value: 72,\n    unit: \"kg\",\n    system: \"http://unitsofmeasure.org\",\n    code: \"kg\",\n  },\n}\n\nObservationSchema.parse(bodyWeight)\n```\n\n### Validate Bundle resources\n\n`BundleSchema` recursively validates known FHIR resources in `entry[].resource`.\n\n```ts\nimport { BundleSchema, type Bundle } from \"fhir-zod/r4/Bundle\"\nimport type { Patient } from \"fhir-zod/r4/Patient\"\n\nconst patient: Patient = {\n  resourceType: \"Patient\",\n  id: \"john-doe\",\n}\n\nconst bundle: Bundle = {\n  resourceType: \"Bundle\",\n  type: \"collection\",\n  entry: [{ resource: patient }],\n}\n\nBundleSchema.parse(bundle)\n```\n\n### Keep FHIR versions explicit\n\n```ts\nimport type { Patient as R4Patient } from \"fhir-zod/r4/Patient\"\nimport type { Patient as R5Patient } from \"fhir-zod/r5/Patient\"\n\nfunction useR4Patient(patient: R4Patient) {\n  return patient.resourceType\n}\n\nfunction useR5Patient(patient: R5Patient) {\n  return patient.resourceType\n}\n```\n\n## Validation scope\n\n`fhir-zod` validates the structural shape of FHIR data while keeping the emitted types close to the base specification.\n\n**Covers:**\n- required fields and cardinality\n- FHIR primitive formats\n- enum and code literal unions from the spec\n- choice-type exclusivity (e.g. `value[x]`)\n- selected constrained reference targets\n\n**Does not cover:**\n- terminology validation\n- FHIRPath execution\n- profile resolution or slicing\n- FHIR server behavior\n\n## Supported FHIR versions\n\n| FHIR release | Version entry point | Resource entry points |\n| --- | --- | --- |\n| R5 | `fhir-zod/r5` | `fhir-zod/r5/\u003cResource\u003e` |\n| R4B | `fhir-zod/r4b` | `fhir-zod/r4b/\u003cResource\u003e` |\n| R4 | `fhir-zod/r4` | `fhir-zod/r4/\u003cResource\u003e` |\n| STU3 | `fhir-zod/stu3` | `fhir-zod/stu3/\u003cResource\u003e` |\n\nEach release exposes two import styles. The version entry point exports shared datatype schemas and supporting generated definitions. Concrete resources are exported from resource entry points:\n\n```ts\nimport { PatientSchema, type Patient } from \"fhir-zod/r4/Patient\"\n```\n\n## Handling empty FHIR strings\n\nFHIR `string` values reject empty strings by default. To accept real-world payloads that use empty strings for the FHIR `string` primitive, configure the root package before parsing:\n\n```ts\nimport { configureFhirString } from \"fhir-zod\"\n\nconfigureFhirString({ allowEmpty: true })\n```\n\nThis setting is process-global and is read when schemas parse input, so it can be applied before or after generated schema modules are imported. It affects all generated schemas that validate FHIR `string` values. It only changes the FHIR `string` primitive. Other primitives such as `date`, `dateTime`, `base64Binary`, `code`, `id`, and `uri` keep their default validation behavior.\n\nTest suites that change this setting should reset it in `afterEach`:\n\n```ts\nafterEach(() =\u003e {\n  configureFhirString({ allowEmpty: false })\n})\n```\n\n## Bundle size and imports\n\nImport concrete resources from their resource entry points:\n\n```ts\nimport { ObservationSchema } from \"fhir-zod/r4/Observation\"\n```\n\nEach FHIR version is exposed as a separate entry point for shared datatypes and supporting generated definitions. Bundlers will tree-shake unused FHIR versions. In frontend code, lazy-load runtime schema imports where validation runs.\n\n```ts\nimport { PatientSchema, type Patient } from \"fhir-zod/r4/Patient\"\n```\n\nSchemas with polymorphic `Resource` fields, such as `Bundle.entry[].resource` and `DomainResource.contained`, include the internal full-resource dispatcher for that FHIR release. This keeps validation independent of import order, but resources with polymorphic fields can pull more schemas into a runtime bundle.\n\n## Specification alignment\n\nSchemas and TypeScript models are generated from pinned official HL7 FHIR definitions, not handwritten schemas or converted TypeScript typedefs. That keeps the public shapes close to the base specification while still fitting into existing Zod-based validation flows. Validation is tested against official FHIR example data from the specification across supported versions.\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for setup, generation, testing, and developer CLI workflow.\n\n## AI and tooling notes\n\nFor development process notes, including AI-assisted workflow details, see [CONTRIBUTING.md](./CONTRIBUTING.md). For AI coding assistants and other tools using this package, see [llms.txt](./llms.txt).\n\n## Acknowledgements\n\n`fhir-zod` was inspired by [fhir.resources](https://github.com/nazrulworld/fhir.resources), the Python library for working with FHIR resources.\n\n## Trademark notice\n\nFHIR® is a registered trademark of Health Level Seven International (HL7). Use of the FHIR® name does not imply endorsement by HL7.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falysivji%2Ffhir-zod","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falysivji%2Ffhir-zod","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falysivji%2Ffhir-zod/lists"}