Documentation
Compared with the alternatives
Interface engines, the mature Java libraries, the other Rust crates, and the pipe-splitting you were about to write yourself. When each is the right answer, and when this project is the wrong one.
First, which kind of thing do you need?
Most comparisons in this space go wrong by putting products from three different categories in one table. The honest first question is what you are building.
- You need to run interfaces — routes, retries, queues, monitoring, on-call
- You want an interface engine. Skip to the next section; a library is not that.
- You are writing an application that happens to speak HL7 v2
- You want a library. That is what this project is.
- You need a one-off transformation at a shell prompt
- You want a command-line tool, and the ones here may be enough on their own — no Rust required.
Interface engines
Open Integration Engine — the community fork of Mirth Connect, after Mirth moved to a commercial-only licence at 4.6 in 2025 — and its commercial siblings are a different category of thing entirely. An engine gives you channels, routing, a management UI, JavaScript transformers, persistence, retry and alerting, and an operations story. It is a system you deploy and run.
A library gives you a function call. If your problem is “forty interfaces, three hospitals, and someone has to be paged when one stops”, an engine is the right answer and no amount of crate is going to substitute for it.
These crates are useful alongside an engine rather than instead of it:
- The service at the end of a channel, where you would otherwise be writing the v2 parsing again.
- A shell-level check or transformation, using the command-line tools, without standing anything up.
- A dedicated high-volume path where a JVM-per-message and a channel round trip are more than the job needs.
HAPI, and the mature libraries
HAPI HL7v2 is the reference open-source HL7 v2 library, in Java, dual licensed under MPL 1.1 and GPL 2.0. It has been maintained for two decades, ships a generated typed model for every segment and message of every release, and has seen far more real-world traffic than anything here. Its .NET port, and the mature Python libraries, are in the same position.
If your platform is the JVM, use HAPI. That is not modesty; a twenty-year-old library with complete release coverage and a large user base is the lower-risk choice, and reimplementing it in a language you were not otherwise using is a bad trade.
Where this project differs, stated as trade-offs rather than wins:
| The mature libraries | Here | |
|---|---|---|
| Release coverage | Complete generated model, every segment, every release | 24 segments, 42 types, 4 structures, extensible in JSON — see Conformance |
| Runtime | A JVM, or a CLR, or a Python interpreter | A static binary, no runtime, no GC |
| Dependency tree | Substantial, and audited as such | One crate, itself dependency-free |
| Track record | Two decades of production traffic | Published in 2026. New. |
| Licence | MPL 1.1 or GPL 2.0 for HAPI | MIT, Apache-2.0, BSD-3-Clause, GPL-2.0-only, or GPL-3.0-only, at your option |
The licensing row is the one that decides some evaluations outright. A permissive option matters if you are linking into a closed-source product; a copyleft option matters if your organisation prefers one. Offering five is how this project avoids having that conversation with anyone.
The other Rust crates
If Rust is already your platform, the existing options are narrower than they first appear. Figures from crates.io, checked 26 August 2026:
| Crate | Latest | Published | Downloads | Scope, as it describes itself |
|---|---|---|---|---|
hl7-mllp-codec | 0.4.0 | 22 July 2022 | 25,755 | A Tokio codec for MLLP framing. Transport only, no v2 semantics. |
hl7-parser | 0.3.0 | 24 February 2025 | 16,625 | Parses message structure; states that it does not validate correctness. |
rust-hl7 | 0.5.0 | 8 September 2021 | 14,777 | Parser and object builder; describes itself as experimental. |
Read those publication dates carefully rather than dismissively. A library that has not been
released in three years may be dormant, or may simply be finished and stable for what it does — hl7-mllp-codec in particular does one small thing and does it well, and if you are
already on Tokio and want framing alone, it remains a reasonable choice.
What none of them offers is the whole span: a release dictionary, validation, mutation and building, format conversion, and both transports, maintained together. That gap is the reason this project exists.
Splitting on pipes yourself
This is the real competition, and usually it is the incumbent: a hundred lines somewhere in the
codebase that split a segment on | and index the result.
// The bug: this is not how HL7 works.
let fields: Vec<&str> = segment.split('|').collect();
let name = fields[5];Each of the following is a production incident that code has already caused somewhere:
- The delimiters are declared by the message, in MSH-1 and MSH-2. The usual set is a convention, not a guarantee, and a sender that uses different ones will be parsed into nonsense rather than rejected.
- Escape sequences mean an ampersand or a backslash inside a value is not what it looks like. Splitting first and decoding later is the wrong order.
- The explicit null is not an empty field. One says “we have nothing here”; the other says “delete what you have on file”. Collapsing the two writes wrong data into a patient record, silently.
- Repetitions, components, and subcomponents are four levels deep, and the naive version handles one.
- MSH is off by one, because MSH-1 is the field separator itself. Every hand-rolled parser meets this bug.
None of that is a reason to feel bad about the hundred lines; it is a reason to replace them with something whose round trip is a test. If you replace them with a different library than this one, the goal is still met.
What this project offers
Stated without adjectives, so you can check each one:
- One dependency.
hl7-2depends oner7, which depends on nothing. That is the whole tree, which matters where dependency trees get audited. - No runtime. A static binary, no JVM, no GC pause, and a command-line tool an integration analyst can use without writing any Rust.
- Byte-for-byte round trip, as a test rather than an aspiration.
- The explicit null kept distinct from an absent value, at every level.
- A stated conformance position — exactly which segments, types, and structures, and what happens outside them.
- A stated position on patient data — what these crates do with it, and where a value can escape into a log.
- An MSRV of current stable minus three, because hospital toolchains are approved on a cycle measured in quarters.
- Five licences, at your option, so licensing is not a conversation.
- A vendor dialect is one JSON file, or generated from your own XSDs.
When this project is the wrong answer
- You need the HL7® FHIR® standard. Not implemented here, at all. The umbrella crate reserves a module path and nothing more.
- You need CDA, or a substantial HL7 v3 implementation. The v3 crate is a foundation — six RIM classes, six data types, a generic envelope — and says so in its own first section.
- You are on the JVM, .NET, or Python already. Use the mature library for your platform. Adding a language to a hospital's supported stack is a bigger decision than picking a parser.
- You need an operations story, not a function call. Routing, retries, queues, monitoring, and an on-call runbook are an interface engine's job.
A fifth, softer one: this project is new, published in 2026, at 0.x. If your risk posture needs a long production track record, it does not have one yet. That is a fact about the calendar, and the only honest thing to do is say so.