The whole clinical backend, as a programming model.

Not another FHIR server — the app backend, the way Convex and Supabase did it for everyone else.

Six pillars

Everything an AI-native health app needs, typed and fresh.

You write typed clinical functions in TypeScript. bonfireDB keeps reads fresh on commit, runs the heavy work async, and generates clean FHIR R4 underneath. Pick a pillar to go deeper.

App-native primitives

Notes, assessments, observations, tasks — typed functions that read and write clean projections, never raw FHIR by default.

Explore primitives →

Always fresh

Operational read models commit on write. Every mutation returns a freshness lifecycle so you always know what's live and what's still computing.

See freshness →

Semantic search

pgvector lives beside the data. Embeddings are computed async and reported in the freshness object — no second store to keep in sync.

Search the chart →

Custom MCP builder

Ship the MCP compiler, not one canned MCP. Every typed function becomes an SDK method, an HTTP endpoint, and an MCP tool.

Build your MCP →

Clinical authorization & audit

Patient- and tenant-scoped by default. Writes are propose-only, every agent read is audited, every result is cited to its source.

Lock it down →

FHIR underneath

FHIR R4 is generated under the hood for export and interop. Call clinical.fhir.export and get a clean Bundle on demand.

Export FHIR →

Offline & local-first sync

Clinics have bad wifi. Optimistic local writes queue and sync on reconnect — the freshness lifecycle extends to sync state.

Go offline →

File & attachment storage

Scanned forms, images, PDFs, scribe audio — stored in your S3, wired to FHIR, with the same ABAC and audit as your data.

Store files →

Terminology & validation

Validate codes on write and power code-pickers across LOINC, SNOMED CT, RxNorm — “store a diagnosis” stops being a project.

Validate codes →

SQL-on-FHIR analytics

SQL-on-FHIR v2 ViewDefinitions materialize flat, fresh-on-commit views with row- and column-level ABAC. Reports, BI, ML — in plain SQL, no Spark.

Query the chart →

Clinically-dense seed data

One command seeds coherent, longitudinal, profile-valid patients into local Postgres — plus per-test snapshot & reset. A realistic patient in 5 minutes.

Seed a clinic →

Security & HIPAA

Runs in your AWS under your own BAA on the OSS tier; encryption, automatic audit, ABAC, and no data lock-in.

See the trust model →
The programming model

Write a function. Get a fresh read back.

This is the whole loop. You call a typed clinical function; the write commits to Postgres and the operational read models update on commit; the response tells you exactly which views are fresh and which indexes are still computing.

clinical.ts
// Create a note — returns a freshness lifecycle object
const result = await clinical.notes.create({ patientId, encounterId, text })
// {
//   status: "committed",
//   views:   { notesByPatient: "fresh", timeline: "fresh" },
//   indexes: { semanticSearch: "pending", agentContext: "pending" }
// }

// Read reactively — commit-ordered updates push to the client
const notes = useClinicalQuery(api.notes.listByPatient, { patientId })

// Record an assessment -> QuestionnaireResponse + Observation
clinical.assessments.record("PHQ-9", { patientId, answers })

// Permission-aware, cited agent context
const ctx = await clinical.agent.sessionPrep({ patientId, windowDays: 90, include: ["recentNotes", "assessments", "tasks"] })

// Clean FHIR R4 Bundle on demand
await clinical.fhir.export(patientId)

Postgres is the source of truth — no Redis. Commit-ordered freshness rides Postgres LISTEN/NOTIFY and logical replication; the async lane uses SKIP-LOCKED. Committed operational read models keep common reads fresh on commit; heavy work — semantic search, embeddings, agent context, complex FHIR search — runs async and reports status in the freshness object. Add a cache or bus only when a measured hot path forces it.

More than a FHIR server

Not just a FHIR server.

A FHIR server stores and exchanges records. bonfireDB is the application backend: the primitives, the freshness, the authorization, the agents — and FHIR generated underneath for when you need it.

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

Spin up the open-source core in your own AWS, or let us run it and sign the BAA. Either way you start with typed functions, fresh reads, and FHIR underneath.

FAQ

Frequently asked questions

What does a TypeScript FHIR backend like bonfireDB give you?

You write typed clinical functions in TypeScript (notes, assessments, observations, tasks) that read and write clean projections instead of raw FHIR. bonfireDB is designed to keep reads fresh on commit, run heavy work async, and generate clean FHIR R4 underneath for export and interop.

Is bonfireDB just another FHIR server?

No. A FHIR server stores and exchanges records; bonfireDB is the app backend that sits above the FHIR server. It provides app-native primitives, fresh-on-commit reads, clinical authorization, and agent context, with FHIR R4 generated underneath when you need it.

How does bonfireDB do realtime without Redis?

Postgres is the source of truth and there is no Redis. Commit-ordered freshness is designed to ride Postgres LISTEN/NOTIFY and logical replication, with the async lane using SKIP-LOCKED. You add a cache or bus only when a measured hot path forces it.

Does bonfireDB support semantic search and vector embeddings?

Yes. pgvector lives beside your clinical data, so there is no second store to keep in sync. Embeddings are computed async and reported in the freshness object returned by each mutation.

Is bonfireDB available to use today?

bonfireDB is in early access and pre-launch. You can join the waitlist to run the open-source core in your own AWS or have us host it under a BAA. Features described here reflect the design and programming model, not a finished product.