
The shift from paper intake forms to FHIR-based digital forms in US healthcare is well underway in 2026, and the technical spine is the Structured Data Capture IG — Questionnaire, QuestionnaireResponse, and the associated rendering and extraction operations. The parts that trip teams up are less about the spec and more about how it interacts with existing intake workflows.
The Questionnaire resource is a form schema, not a form.
A Questionnaire resource defines items, types, and constraints — but rendering it in a browser or on a tablet requires a separate rendering engine. Two open-source options in 2026:
- LHC-Forms from the NLM — reference renderer, widely used for research protocols, ships as a web component. - NLM Form Builder — authoring tool that emits SDC-conformant Questionnaires.
Commercial options are more numerous. What matters for a healthcare deployment: the renderer must support conditional logic (enableWhen), value set-bound choice items, and the initialExpression / calculatedExpression extensions that make dynamic forms possible.
QuestionnaireResponse binding to source resources is where the value lives.
A form fill-in is only useful if the answers get extracted into structured FHIR resources — Observation, Condition, Patient extensions, etc. The SDC IG defines Questionnaire.item.extension extraction directives that tell an extractor how to map each answer to a target resource. The two extraction patterns:
1. Definition-based extraction: each item has a definition URL pointing to a StructureDefinition element. The extractor walks the Questionnaire, reads answers, populates the referenced element. Simple, works well for straightforward forms. 2. StructureMap-based extraction: a separate StructureMap resource defines the transformation. More flexible for complex forms where one answer maps to multiple resources.
Most production deployments use definition-based; StructureMap extraction is powerful but requires an execution engine (very few production-ready implementations exist).
enableWhen logic complexity often exceeds spec intent.
Real intake forms have deep conditional trees: "if PatientAge > 65 and PatientSex = 'Female' and question X answered 'yes', show questions Y and Z." enableWhen handles single-condition branches natively; multi-condition logic requires the FHIRPath expressions via the enableWhenExpression extension. Renderers that only support the basic enableWhen element quietly break on multi-condition logic. Test against real intake forms, not spec examples.
Save-and-resume is where UX credibility is won.
Unfinished QuestionnaireResponses need to persist server-side and be re-loaded on session return. The FHIR pattern: POST QuestionnaireResponse with status: in-progress, PUT to update as user progresses, PUT with status: completed at finish. The pitfall: some renderers don't emit intermediate saves without explicit UI trigger; unsaved state disappears on tab close.
Integration with intake workflows
Digital forms rarely stand alone — they feed into scheduling, insurance verification, and clinical charting. The integration points that matter:
- Pre-visit intake: patient completes Questionnaire before arrival, QuestionnaireResponse is available at check-in. - In-visit updates: clinician sees pre-visit responses, adds or amends in the EHR's chart interface. - Post-visit extraction: extracted Observations flow into the clinical timeline.
Vendor landscape (mid-2026)
| Tool | Authoring | Rendering | Extraction | Best fit |
|---|---|---|---|---|
| LHC-Forms + NLM Form Builder | Yes | Yes (web) | Definition-based | Research, open |
| Smile CDR SDC module | Via HAPI | Yes | Both | HAPI stacks |
| Aidbox Formbox | Yes | Yes (web, mobile) | Both | Aidbox stacks |
| Firely SDC.NET | Yes | Yes | Definition-based | .NET stacks |
Digital forms on FHIR are a solved problem in 2026 provided you pick a renderer that handles conditional logic depth, an extractor that fits your target resources, and a save-and-resume model that survives real user sessions. The spec supports the ambitious use cases; the operational reality is that most gaps live in the last-10% of renderer feature coverage.