HL7 v2

Parse HL7 v2 in TypeScript, vendor quirks included.

@cosyte/hl7 reads the HL7 v2 messages real systems send, hands you the fields by name, and reports every deviation it tolerated as a warning with a stable code. MIT-licensed, with zero runtime dependencies.

@cosyte/hl7
npm install @cosyte/hl7

Need it integrated? Talk to us.

The standard

HL7 v2 is the message format most hospital interfaces still speak.

@cosyte/hl7

Fields by name, with the full segment tree underneath.

It is for the developer who has to consume HL7 v2 traffic without becoming an HL7 expert first. msg.patient?.mrn and msg.meta.timestamp are the whole learning curve, and the positional tree is one accessor away when you need it.

  • Three ways in: named helpers such as msg.patient and msg.observations(), dot-paths such as msg.get("PID.5.1"), and structural traversal.
  • Lenient by default: 20 stable warning codes record what was tolerated, strict mode turns every deviation into an error for CI, and only 4 structural failures are always fatal.
  • Round-trip safe: parse, modify and serialize back to spec-clean HL7, with escape sequences re-emitted byte for byte.
  • Opt-in validation against HL7's published message structures, or against a conformance profile you write.
  • 8 built-in vendor profiles, and defineProfile() for your own trading partners.
  • parseStream reads batch files too large to hold in memory.
  • No logging, no network and no file access. A warning carries a code and a position, never the field value.
quickstart.tsts
import { parseHL7 } from "@cosyte/hl7";

// A synthetic ADT^A01 admit. HL7 v2 ends every segment with a carriage return.
const raw =
  "MSH|^~\\&|EPIC|MAIN|LIS|REF|20260419101500||ADT^A01^ADT_A01|MSG00001|P|2.5\r" +
  "EVN|A01|20260419101500\r" +
  "PID|1||MRN12345^^^HOSP^MR||Doe^John^Q||19800115|M|||123 Main St^^Boston^MA^02101||^PRN^PH^^^617^5551212\r" +
  "PV1|1|I|ICU^101^A^HOSP|||||ATTEND^Smith^Jane^^^^MD|||||||||||VISIT001\r";

const msg = parseHL7(raw);

console.log("Patient record number:", msg.patient?.mrn);
console.log("Full name:", msg.patient?.fullName);
console.log("Date of birth:", msg.patient?.dateOfBirth?.raw);
console.log("Precision:", msg.patient?.dateOfBirth?.precision);
console.log("Message type:", msg.meta.type);
console.log("Sent at:", msg.meta.timestamp?.raw);
console.log("Ward:", msg.visit?.location?.pointOfCare);

From the @cosyte/hl7 README on GitHub, verbatim. Every value in it is synthetic.

Limits

What it does not do.

Its README names what is out of scope. The short version:

  • It is a parser, not a transport. MLLP framing and acknowledgements are @cosyte/mllp.
  • It does not read HL7 v3 or CDA documents. C-CDA is @cosyte/ccda.
  • It does not convert to FHIR. That is @cosyte/transform.
  • It validates structure, not every HL7 table. Coded values need a domain validator of your own.
  • A fatal parse error carries up to 40 characters of the input, unredacted, so the error is actionable. Strip it before logging if your policy requires.
  • Storage, transport security, retention, audit and access control stay with your application.

The full status and limits, in the README

Alternatives

What else you could use.

Each description comes from the project’s own page or npm listing, linked below. Where we name a difference, you can check it there.

Java library

HAPI HL7v2

An open-source, object-oriented HL7 2.x parser for Java; its site says JDK 11 or later is required. The natural choice when your service runs on the JVM. @cosyte/hl7 is for Node.js and TypeScript.

Source: HAPI HL7v2 project site

Node.js library

node-hl7-client

An MIT-licensed Node.js client that sends HL7 messages to a server and can parse them; node-hl7-server is its receiving side. Transport and parsing come together there. We keep them apart, in @cosyte/mllp and @cosyte/hl7.

Source: npm, node-hl7-client

JavaScript library

hl7-standard

An Apache-2.0 module for transforming, manipulating and creating HL7 messages, usable on its own or inside an engine such as Mirth. Its latest npm release dates from May 2022, and it ships no type declarations.

Source: npm, hl7-standard

Integration engine

Mirth Connect

NextGen Healthcare's integration engine. From version 4.6 it moved to a single closed-source, proprietary license, and the source code for new releases is no longer public. An engine is a server you configure; a library is code inside your own service.

Source: NextGen Healthcare, Mirth Connect downloads

Works with

  • MLLP@cosyte/mllp moves HL7 v2 over TCP: framing, acknowledgements and reconnects.
  • @cosyte/transformMaps parsed HL7 v2 messages to FHIR R4 resources, following HL7's v2-to-FHIR implementation guide.
  • @cosyte/synthGenerates spec-clean synthetic HL7 v2 messages for your tests, the same bytes for the same seed.
  • De-identification@cosyte/deid applies a HIPAA Safe Harbor policy to a parsed HL7 v2 message.
  • @cosyte/cliParse an HL7 v2 file from a terminal, or give an agent the same parser over MCP.
  • @cosyte/datesConverts and validates the dates the @cosyte parsers return, without inventing a midnight or a timezone.

Try @cosyte/hl7 on your own messages.

It is free and MIT-licensed. If it saves you a day, a star on GitHub helps other engineers find it.

Need it integrated? Talk to us, or see what our integration services cover.