Comparison

How this compares

Interface engines, the mature libraries on other platforms, the other Rust crates, and the pipe-splitting you were about to write yourself. When each is the right answer, and when this is the wrong one.

No performance comparison is claimed here. Nothing in this family has been benchmarked against another library. Comparing fairly means matching what each one actually does, and a parser that only splits on pipes is not doing the same work as one that preserves escape sequences and round-trips byte for byte. So this page compares capability and shape, which is checkable, rather than speed, which would not be. Our own measured figures, with their method, are on the benchmarks page.

First, which kind of thing do you need?

Most comparisons in this space go wrong by putting products from three different categories into one table. The honest first question is what you are building.

If you need to…You wantThis family
Run interfaces: routes, retries, queues, monitoring, on-callAn interface engineNot that. Useful alongside one.
Write an application that happens to speak HL7® v2A libraryYes — er7, er7-redact, serde-er7
Do a one-off transformation at a shell promptA command-line toolYes — two binaries, no Rust knowledge required
Validate a message against the standard’s tablesA conformance toolNo. Deliberately out of scope.
Speak the HL7® FHIR® standardAn HL7® FHIR® libraryNo. Different standard entirely.

Interface engines

Open Integration Engine — the community fork of Mirth Connect, made after Mirth moved to a commercial-only license — and its commercial siblings are a different category of thing entirely. An engine gives you channels, routing, a management UI, transformers, persistence, retry, 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 substitutes 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 in whatever language that service is in.
  • A shell-level check, redaction, or normalisation, using the command-line tools, without standing anything up.
  • Getting a message into a bug report. er7-redact --report prints the paths and actions with no values in the output, which is the shape a ticket can carry.

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 traffic than anything here. NHapi is its .NET port; hl7apy is the best-established Python option.

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.

The mature librariesHere
Typed modelComplete generated model: every segment, every releaseNone. A structural tree; meaning comes from the path
ValidationConformance checking against the standard’s tablesNone, on purpose
RuntimeA JVM, a CLR, or a Python interpreterA static binary: no runtime, no GC
Dependency treeSubstantial, and audited as suchZero, one, and two crates respectively
Round tripVaries by parser and optionsByte for byte, as a tested guarantee
Track recordTwo decades of production trafficFirst published 2026-08-15. New.
LicenseMPL 1.1 or GPL 2.0, for HAPIFive, at your option

The license row 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

A small field, and cooperation beats competition in it. The figures below were read from the crates.io API on 2026-08-26, as context rather than as a ranking.

hl7-parser

0.3.0 · last published 2025-02 · 16,640 downloads

The most-used and most actively developed alternative. Parses structure without validating; optional Serde, and timestamps into chrono, time, or jiff; message building; cursor-by-character-index. Apache-2.0.

hl7v2-parser

1.2.0 · last published 2026-03 · 209 downloads

Newer. Zero-allocation where possible; a companion hl7v2_stream gives event-based streaming with bounded memory.

rust-hl7

0.5.0 · last published 2021-09 · 14,777 downloads

Buffer-copy-free indexing with HL7® notation; self-described as experimental; explicitly no plan for conformance checking. Last published 2021.

hl7-mllp-codec

0.4.0 · last published 2022-07 · 25,755 downloads

Not a parser at all: a Tokio codec for MLLP framing. Complementary to any of these, including er7.

When to choose one of those instead

These are real reasons, not hedges.

  • You want timestamp types. hl7-parser parses HL7 timestamps into chrono, time, or jiff. er7 returns the text and leaves the interpretation to you, because doing otherwise means a dependency.
  • You want streaming with bounded memory over very large inputs. hl7v2_stream is built for that; er7 parses a message into a tree.
  • You want Serde on the parser itself. hl7-parser has a feature flag. Here it is a separate crate, precisely so that users who do not want Serde do not pay for it.
  • You are already using one and it works. Switching a working HL7 parser is rarely the highest-value thing on anyone’s list.

Where these crates differ

  • Zero runtime dependencies in er7, enforced by a test. The dependency table is empty and a test fails if that changes. Criterion lives in a separate unpublished workspace member so that even the development dependencies stay empty.
  • A command-line tool, not only a library. Every label in its output is a valid query you can paste back in.
  • Redaction as a first-class, separately published thing. er7-redact has no equivalent in the list above.
  • Specification-first development. Every behaviour is a numbered rule, and each rule names the test that enforces it — checkable by reading the tree.
  • Five licenses, where the alternatives above are Apache-2.0 or MIT.

Splitting on pipes yourself

The honest comparison, because it is what most teams actually do and it is sometimes right.

fields = line.split("|")          # this works, until it doesn't

When hand-rolling is right: you read one field, from one sender, whose messages you control, in a script that will not outlive the week.

When it stops being right, in roughly the order teams discover it:

  1. Escape sequences. \F\ is a literal | in a value. Splitting on | cuts a value in half, silently.
  2. The MSH segment is special. MSH-1 is the field separator, so the segment does not index like any other.
  3. A sender who does not use the default delimiters. They are declared in MSH-2 and you are expected to read them, not assume them.
  4. Repeating fields. PID-13 may be one phone number or four, and the code that assumed one is now wrong.
  5. Components and subcomponents go two levels deeper.
  6. Writing. Now you need to escape on the way out, and an unescaped delimiter breaks the message for everyone downstream.
  7. Round-tripping. Someone asks why the message that came out is not byte-identical to the one that went in, and the answer is a week.

The pitch is not “your split is wrong”. It is that the seven items above are exactly what er7 implements, in about the same runtime cost, with a test for each and no dependency to audit.

What none of these crates do

Stated here so no comparison implies otherwise.

  • No validation or conformance checking. Structure is parsed; content is not judged.
  • No typed segment model. No generated class per segment.
  • No transport. No MLLP, no TCP, no SOAP.
  • No HL7® FHIR® standard support, and no v2-to-FHIR® mapping.
  • No clinical claim. These are encoding libraries, not medical devices, and nobody has certified them.

Each crate’s own specification states its scope and its non-goals precisely; that is the authoritative version of this list. The full write-up, with the reasoning, is COMPARISONS.md in the repository.