Bridging the Healthcare Divide: Building an HL7-to-FHIR Transformation Pipeline with Mirth Connect & Node.js

By Hisham Alrashdan — Healthcare Integration Engineer

In the world of healthcare technology, we are often caught between two eras. On one side, we have legacy Electronic Medical Records (EMR) systems speaking HL7 v2.5—a pipe-delimited text standard from the 1980s. On the other, we have modern cloud platforms, analytics tools, and mobile apps expecting FHIR R4—a robust, RESTful JSON standard.

Bridging this gap usually requires expensive middleware or months of manual integration.

I built InfoGleam Health as a Proof of Concept (PoC) to demonstrate how we can solve this interoperability challenge using open-source tools, modern DevOps practices, and a microservices architecture.

Note: Mirth Connect was open source up to version 4.5.2. From version 4.6 (March 2025) it is commercial. This project runs on Open Integration Engine (OIE), the open-source continuation of Mirth Connect. The same channel also works on Mirth Connect 4.5.2.

The Problem: The “Tower of Babel” in Hospitals

The core engineering challenge in healthcare interoperability is data normalization.

  • Legacy Systems emit streams of cryptic text (HL7) via MLLP (a raw TCP/IP protocol).
  • Modern Systems require structured JSON resources via HTTP/S.

Without a bridge, these systems cannot communicate. My goal was to create a Reference Implementation that automates this translation in real-time, is easy to deploy, and separates the parsing logic from the business logic.

The Solution: InfoGleam Health

InfoGleam Health is a lightweight, containerized pipeline that ingests HL7 v2.5 messages and outputs a FHIR R4 Patient resource.

The architecture is designed around “Separation of Concerns.” Rather than building a monolithic application, I decoupled the message transport from the transformation logic.

High-Level Architecture

The system runs on Docker Compose and consists of three distinct layers:

  1. Ingestion layer (OIE or Mirth Connect): the integration engine. It listens for HL7 messages over MLLP and parses them.
  2. Transformation Layer (Node.js/Express): A microservice that handles the complex logic of mapping raw data into the FHIR schema.
  3. Orchestration (Docker): A unified environment that allows the entire stack to spin up with a single command.

Why I Decided to Separate Mirth and Node.js

A common approach is to do everything inside Mirth Connect using its internal JavaScript engine. However, for this project, I made an architectural decision to offload the heavy transformation logic to a dedicated Node.js service.

My reasoning was twofold:

  1. Modern tooling: Node.js has npm and standard test tools. Code inside the engine runs in its Rhino JavaScript engine, which is hard to test outside the engine.
  2. Testability: all mapping rules are in one Node.js file. The repo has 37 automated tests.

Technical Implementation: The Data Flow

Here is how the system processes a patient admission event (ADT^A01) in real-time.

Step 1: Ingestion

The hospital system sends a raw HL7 string. To the untrained eye, it looks like noise:

MSH|^~\&|HOSPITAL_SYSTEM|INFOGLEAM_REF|MIRTH|FHIR_SERVICE|20260112093045||ADT^A01|MSG00001|P|2.5
PID|1||TEST000001^^^INFOGLEAM^MR||PATIENT^TEST^A||19700101|U|||100 TEST STREET^^TESTVILLE^TS^00000^USA||(555)0100|||S||ACC000001|

Step 2: Parsing & JSON Conversion

The engine receives this message over MLLP on port 6661. A filter lets only patient events pass (ADT A01, A04, A05, A08, A28 and A31). A short JavaScript step copies the PID fields (ID, name, birth date, gender, address and phone) into JSON and posts it to the Node.js service.

Step 3: FHIR Normalization (The Heavy Lifting)

The Node.js service receives the raw JSON and applies the FHIR R4 schema rules. This is where the engineering complexity lies—handling date formats, mapping gender codes, and structuring arrays.

// Real output from the test run on 30 Oct 2026. There is no id, because the app does not store the Patient.
{
  "resourceType": "Patient",
  "identifier": [
    {
      "type": {
        "coding": [
          {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "MR",
            "display": "Medical record number"
          }
        ]
      },
      "system": "https://example.org/fhir/mrn",
      "value": "TEST000001",
      "assigner": {
        "display": "INFOGLEAM"
      }
    }
  ],
  "name": [
    {
      "family": "PATIENT",
      "given": [
        "TEST",
        "A"
      ]
    }
  ],
  "telecom": [
    {
      "system": "phone",
      "value": "(555)0100",
      "use": "home"
    }
  ],
  "gender": "unknown",
  "birthDate": "1970-01-01",
  "address": [
    {
      "line": [
        "100 TEST STREET"
      ],
      "city": "TESTVILLE",
      "state": "TS",
      "postalCode": "00000",
      "country": "USA"
    }
  ]
}

Developer Experience (DX)

One of my primary goals was usability. Integration engines are notoriously difficult to set up. I used Docker, so any developer can start the project with a few commands. You need Docker and Node.js 22.

git clone https://github.com/Hisham-InfoGleam/infogleam-health-poc
cd infogleam-health-poc
npm start   # starts OIE and the FHIR app in Docker
# import and deploy mirth-config/adt_to_fhir_channel.xml (see the README)
npm run test:send-hl7   # sends a test ADT^A01, expects AA

Disclaimer: From Demo to Production

It is important to note that InfoGleam Health is a Proof of Concept. While the logic is sound, a production environment requires strict adherence to HIPAA/GDPR regulations. To take this from “Demo” to “Live,” the following would be required:

  • Security: Implementing TLS 1.3 for all transport layers and OAuth2 for API authorization.
  • Persistence: Replacing the in-memory processing with a durable message queue (like RabbitMQ) to ensure no data is lost during a crash.
  • Auditing: Comprehensive logging of every data access event.

Conclusion

This project served as a deep dive into the complexities of healthcare interoperability. It demonstrates that by combining an integration engine such as OIE or Mirth Connect with modern microservices patterns in Node.js, we can build systems that are robust, testable, and ready for the future of digital health.

You can view the full source code, run the simulation, and check out the documentation on my GitHub.

More from the blog

De-Mystifying Healthcare Apps: A “SMART on FHIR” Starter Kit for Developers

By Hisham Alrashdan — Healthcare Integration Engineer Building a healthcare app is not like building a standard web app. You cannot just "login with email"...