Perfuse

Open-source healthcare integration engine

HL7 v2 · FHIR · DICOM · X12 · CDA — in one static binary

An Apache-2.0 alternative to Mirth Connect. Your existing Mirth JavaScript runs unchanged.

31 MBmemory at rest, against Mirth's 383 MB
One fileno JVM, no installer, no database
Apache 2.0no licence fee, ever
Download Perfuse for Linux, x86-64 Download Perfuse for macOS, Apple Silicon Download Perfuse for Windows, x64

Intel Macs, ARM64 Linux, ARM64 Windows and checksums · Source on GitHub

Reference manual · Migrating from Mirth Connect

What it is

A lab sends results in HL7 v2. An imaging department speaks DICOM. A payer sends X12. The system receiving all of it wants FHIR. Perfuse sits in the middle, parses each of them properly, transforms what needs transforming, and delivers without losing anything.

Perfuse sits between clinical systems: a lab system over MLLP, radiology over DICOM and a payer over X12 arrive on one side; Perfuse parses, filters, transforms, queues and delivers; an EHR over FHIR, a downstream system over MLLP and an archive over SFTP receive on the other.

It is written in Go, licensed under Apache 2.0, and runs on Linux, macOS and Windows with nothing installed beside it. The web console is compiled into the binary, and everything the configuration files can express can also be done from the browser — a feature reachable only from YAML is treated as a bug.

Try it against your own traffic without asking anyone

Coming from Mirth? The migration guide covers E4X, what converts and what refuses.

You do not need a contract, a vendor relationship or anyone's approval to find out whether this works on your messages. Add one destination to your existing Mirth channel that forwards a copy to Perfuse, and give the Perfuse channel a directory as its only destination. Nothing reaches a downstream system, because there is nothing else for it to send to.

# 1. What would stop you, before you commit to anything
perfuse explain mirth-channel-export.xml

# 2. Convert it
perfuse translate mirth-channel-export.xml -o channels/

# 3. Run it beside Mirth on real traffic, delivering nothing to anyone
perfuse run channels/labs.yaml

# 4. Prove the two engines agree, on your own messages
perfuse compare -left-name Mirth -right-name Perfuse mirth-out/ perfuse-out/

perfuse compare pairs the two directories by message control id and reports where they disagree, grouped by cause — so three thousand messages differing for one reason are one finding, not three thousand. Message content is withheld by default, because a report is a thing people paste into tickets.

perfuse explain is worth running first. It tells you what converts cleanly, what converts with caveats, and what does not convert at all — by name, not as a count. A migration that surprises you in week three is worse than one that refuses on day one.

Against Mirth Connect

PerfuseMirth Connect
Memory at rest31 MB383 MB
RuntimeNone. One static binaryOpenJDK 17 plus an install
Install sizeOne file254 MB plus the JRE
LicenceApache 2.0, and staying that wayClosed source since 4.6 — commercial only
Existing Mirth JavaScriptRuns unchanged, including E4XNative
KafkaSource and destination, keyed for per-patient orderingNo connector
Config in the browserEverything, by policyMost things
Multi-server viewFleet view, includedA paid feature
Production track recordNone yet. v0.1.3Twenty years, thousands of sites

That last row is the honest one. Perfuse v0.1.3 has never processed production clinical traffic, and the Windows and ARM64 Linux binaries have never been executed at all. Everything that was verified is recorded, and so is everything that was not. Evaluate it in parallel, against real messages, with the incumbent still delivering — and decide from your own evidence rather than this page.

What it does

The full itemised list is in the README, fifteen areas, with the partial ones marked as partial. Every setting is described in the reference manual.

Verified against real software, not mocks

Interoperability claims are cheap. Perfuse's SAML was tested against real Keycloak and real Microsoft Entra, its Mirth import against a real Mirth Connect export, its FHIR output against HAPI, and its DICOM against Orthanc. Two of those found defects in the other party.

It is also measured against other people's data rather than only its own. All 2,912 example files published with the FHIR R4 specification were run through it: 13,723 resources validated, none reported wrongly, and every refusal names the type it cannot read. The HAPI HL7 v2 test corpus — the reference Java implementation's own awkward material — parses completely, 59 of 59.

And the question nobody answers: what happens when it is killed? Terminated with SIGKILL part way through a batch, at five different points, 255 messages were acknowledged and 255 were present downstream. None lost, none duplicated. The numbers for the faster acknowledgement mode, which loses almost everything in flight, are published alongside, because a setting like that should be chosen knowing the size of it.

What was tested, what it found, and what was never run →

Getting help

Perfuse is developed and maintained by BioDream LLC. Bug reports are welcome as GitHub issues. Code contributions are not accepted — the source has a single maintainer by design, which is worth knowing before you build on it.