flat-fhir
v0.1.4
Published
Convert FHIR JSON bundles into flat, LLM-friendly XLSX spreadsheets
Maintainers
Readme
flat-fhir
Convert FHIR JSON bundles into flat, LLM-friendly XLSX spreadsheets.
Machines speak FHIR. Humans and LLMs get spreadsheets.
Live Demo | PyPI (Python) | GitHub
Install
npm install flat-fhirQuick Start
import { FlatFHIR, flatten } from "flat-fhir";
// From a file
const ff = new FlatFHIR("patient_bundle.json");
// From a JS object
const bundle = JSON.parse(fs.readFileSync("patient_bundle.json", "utf-8"));
const ff2 = new FlatFHIR(bundle);
// Write to XLSX
await ff.toXlsx("patient_record.xlsx");What It Produces
A multi-sheet XLSX workbook. Every row follows the same structure:
primary_key | performer (who) | timestamp (when) | ...all the whats- primary_key — deterministic SHA-256 hash, unique per row
- performer — the doctor, lab, or pathologist who recorded it
- timestamp — when the observation/event happened (ISO 8601)
- ...whats — the actual clinical data, flattened into columns
Sheets
| Sheet | Description | Example Columns |
|---|---|---|
| patient | Demographics | family_name, given_name, birth_date, gender, phone, email, address |
| vitals | Physical measurements | blood_pressure_systolic_mmhg, heart_rate_bpm, body_temperature_c, oxygen_saturation_pct, body_weight_kg, bmi_kg_m2 |
| labs | Laboratory results | hba1c_pct, glucose_mg_dl, total_cholesterol_mg_dl, creatinine_mg_dl, hemoglobin_g_dl, wbc_k_ul |
| medications | Prescriptions | medication_name, rxnorm_code, dose, dose_unit, frequency, route, status |
| conditions | Diagnoses | condition_name, icd_code, snomed_code, clinical_status, severity |
| allergies | Allergy records | substance, reaction, severity, criticality |
| procedures | Clinical procedures | procedure_name, snomed_code, body_site, outcome, status |
| imaging | Imaging studies | modality, body_site, dicom_uid, findings |
| immunizations | Vaccinations | vaccine_name, cvx_code, dose, lot_number, status |
| encounters | Visit metadata | class, type, facility, reason, status |
| diagnostic_reports | Lab groupings | report_name, loinc_code, conclusion, result_references |
API
import { FlatFHIR, flatten, unflatten, merge } from "flat-fhir";
// Fine-grained control
const ff = new FlatFHIR("bundle.json");
// Access individual sheets as arrays of row objects
ff.patient; // [{ family_name: "Doe", given_name: "Jane", ... }]
ff.vitals; // [{ performer: "Dr. Chen", timestamp: "2024-12-01", blood_pressure_systolic_mmhg: 115, ... }]
ff.labs;
ff.medications;
ff.conditions;
ff.allergies;
// List non-empty sheets
ff.sheets(); // ["patient", "vitals", "labs", ...]
// Output formats
await ff.toXlsx("record.xlsx");
ff.toCsv("vitals.csv", "vitals");
ff.toJson("record.json");
// Round-trip back to FHIR
const bundle = ff.toFhir();
// LLM-friendly text summary
const prompt = ff.toPrompt();
// XLSX back to FHIR Bundle
const restored = await unflatten("record.xlsx", "bundle.json");
// Merge multiple bundles
const merged = await merge(["hospital_a.json", "clinic_b.json"], "merged.xlsx");CLI
# Basic conversion
flat-fhir convert patient_bundle.json -o patient_record.xlsx
# Only specific sheets
flat-fhir convert bundle.json -o record.xlsx --sheets vitals,labs
# From a FHIR server (auto-appends $everything for Patient URLs)
flat-fhir fetch https://fhir.example.com/Patient/123 -o record.xlsx
# Merge multiple bundles
flat-fhir merge hospital_a.json clinic.json -o merged.xlsx
# Reverse: XLSX back to FHIR
flat-fhir unflatten record.xlsx -o bundle.jsonLLM Integration
const ff = new FlatFHIR("bundle.json");
const prompt = ff.toPrompt();Output:
## Patient: Jane Doe, M, DOB 1990-05-15
## Active Conditions
- Type 2 diabetes mellitus (diagnosed 2024-01-10)
- Essential hypertension (diagnosed 2024-09-12)
## Allergies
- Penicillin (causes Skin rash)
## Active Medications
| medication | dose | frequency |
|---|---|---|
| Metformin 500 MG Oral Tablet | 500 mg | twice daily |
| Lisinopril 10 MG Oral Tablet | 10 mg | once daily |Built-in LOINC Registry
219 LOINC code mappings covering FHIR R4 profiles: vital signs, CBC, BMP/CMP, lipid panel, thyroid, HbA1c, renal, coagulation, cardiac markers, blood gases, inflammatory markers, vitamins, and urinalysis.
import { registry } from "flat-fhir";
// Look up a code
const mapping = registry.lookupCode("http://loinc.org", "8867-4");
// { code: "8867-4", column_name: "heart_rate_bpm", sheet: "vitals", unit: "/min" }
// Add custom mappings
registry.add("CUSTOM-1", "my_test_col", "labs");
// Load from file
registry.load("custom_mappings.json");Round-Trip Fidelity
FHIR Bundle JSON -> flatten -> XLSX -> unflatten -> FHIR Bundle JSONResource IDs and code systems (LOINC, SNOMED, ICD-10, RxNorm, CVX) are preserved for lossless round-trips.
Testing
118 tests covering all extractors, output formats, round-trip paths, and 27 external FHIR fixtures (HL7, Synthea, NDHM, InterSystems, IBM).
npm test
# With coverage
npm run test:coverageLicense
MIT
