๐Ÿ”ฅ FHIR underneath

Your app code thinks in notes, sessions and assessments. FHIR R4 โ€” core profiles โ€” is generated beneath them, there when you need to export or integrate, invisible when you don't.

The split

FHIR is for interoperability. It is not your app's data model.

FHIR R4 was designed to move records between organizations that don't trust each other. That's the right tool for export and integration โ€” and the wrong tool to reach for on every screen of one app you control. bonfire keeps both: app-native primitives on top, FHIR R4 (core profiles) generated underneath.

The mapping

Every primitive has a FHIR shadow

You write to clean primitives. bonfire keeps the corresponding FHIR R4 resource in sync underneath, so a clean Bundle is always one call away.

App primitive FHIR R4 resource (underneath)
NoteDocumentReference
Session / visitEncounter
Assessment answersQuestionnaireResponse
Assessment scoreObservation
Symptom eventObservation
Follow-upTask
Care planCarePlan
PatientPatient
ClinicianPractitioner

You never hand-build a resource graph or chase references to write a note. You call clinical.notes.create(...); the DocumentReference, its Encounter link, and the rest are generated and kept consistent for you โ€” fresh on commit.

Export on demand

A clean FHIR R4 Bundle in one call

When interoperability actually matters โ€” sharing a record, leaving the platform, integrating with an EHR โ€” ask for the Bundle. Your app never had to speak FHIR to get here.

export.ts
// Generate a FHIR R4 Bundle (core profiles) on demand
const bundle = await clinical.fhir.export(patientId);

// Patient, Encounters, DocumentReferences, Observations,
// QuestionnaireResponses, Tasks, CarePlans โ€” references resolved.
bundle.resourceType; // "Bundle"
bundle.type;         // "collection"

SMART-on-FHIR read is on the roadmap

Bundle export ships today. SMART-on-FHIR read โ€” pulling standardized resources from a partner that exposes a SMART API โ€” is planned, not yet shipped. The shape is the same on your side: app-native primitives, standard wire format at the edge.

  • Today: export the generated R4 Bundle for sharing or migration
  • Roadmap / planned: SMART-on-FHIR read where the integration target supports it
  • The intent โ€” interop is a feature at the edges, not the substrate you code against
integrate.ts
// FHIR stays at the edges โ€” export today, SMART read planned
const bundle = await clinical.fhir.export(patientId);

// Your app code keeps thinking in primitives
const notes = useClinicalQuery(api.notes.listByPatient, { patientId });
Honest scope

This is scoped conformance โ€” not a full enterprise FHIR server

bonfireDB is pre-launch / early access. The mapping covers the core resource types and common search paths that outpatient apps actually use first. It is deliberately not trying to be HAPI, HealthLake, or Medplum โ€” those are mature, full FHIR servers, and if you need one as your interoperability hub, they earn that job. bonfire exports clean R4 to hand off to one.

What bonfire is

  • FHIR R4 generated underneath your app primitives
  • Core resource types first (Patient, Encounter, DocumentReference, Observation, QuestionnaireResponse โ€” plus Task, CarePlan, Practitioner)
  • Common search paths before exhaustive search coverage
  • Clean Bundle export today; SMART-on-FHIR read planned

What it is not (yet)

  • A full enterprise FHIR server with every resource type and search parameter
  • A drop-in replacement for HAPI / HealthLake / Medplum as the system of record for strangers
  • A federation hub for cross-organization record exchange

If you need a full FHIR server as your interoperability hub, that's a different job โ€” see the comparisons for where dedicated FHIR servers fit and where bonfire exports clean R4 to them.

New to the model? FHIR explained for app developers walks through the resource graph, and why build on FHIR (and when not to) covers when generating it underneath beats reaching for it on every screen.

You build the app. Bonfire is the clinical data layer underneath.

Build on app-native primitives. Let FHIR R4 (core profiles) generate underneath, fresh on commit โ€” there for export and interop, invisible the rest of the time.

FAQ

Frequently asked questions

How do I generate a FHIR R4 Bundle from my app data?

Call clinical.fhir.export(patientId). bonfireDB keeps a FHIR R4 resource (core profiles) in sync underneath your app primitives, so it assembles a Bundle of type "collection" โ€” Patient, Encounters, DocumentReferences, Observations, QuestionnaireResponses, Tasks, and CarePlans โ€” with references resolved, in one call.

Do I have to write FHIR resources to store clinical data in bonfireDB?

No. You write to clean app primitives like clinical.notes.create(...), and bonfireDB generates the corresponding FHIR R4 resource and its links underneath, kept fresh on commit. You never hand-build a resource graph or chase references.

Which FHIR resources does bonfireDB map to?

Core resource types outpatient apps use first: Note maps to DocumentReference, Session to Encounter, assessment answers to QuestionnaireResponse, scores and symptom events to Observation, follow-ups to Task, care plans to CarePlan, plus Patient and Practitioner.

Is bonfireDB a full FHIR server like HAPI, HealthLake, or Medplum?

No. bonfireDB is pre-launch and offers scoped conformance โ€” core resource types and common search paths โ€” not a full enterprise FHIR server. It generates FHIR R4 underneath and exports clean Bundles to a full server when you need an interoperability hub โ€” it doesn't run on top of one.

Does bonfireDB support SMART-on-FHIR?

Bundle export ships today. SMART-on-FHIR read โ€” pulling standardized resources from a partner that exposes a SMART API โ€” is on the roadmap and not yet shipped. The design keeps interop at the edges while your app code stays on app-native primitives.