Here's the uncomfortable truth about most online HL7 tools. You paste a message in, click validate, and that message (names, MRNs, dates of birth, diagnoses) gets POSTed to someone else's server. If the message is real, you've just disclosed PHI to a third party you almost certainly don't have a Business Associate Agreement with.
This post is about doing the same job without that risk.
Why this is a real problem, not a theoretical one
Developers reach for an online validator at exactly the wrong moment. A production interface is misbehaving, and the fastest way to see why is to paste the actual failing message. That message is real patient data. A traditional validator that does its work server-side now has that PHI in its logs, its error tracker, and possibly its analytics, none of which you control.
The usual workaround is to hand-scrub the message first. That's slow and error-prone (miss one field and you've still leaked), and it changes the very data you're trying to debug, so the validator may no longer reproduce the problem.
The fix: validate in the browser
The cleaner answer is to run the parser and validator entirely client-side. The message is parsed by JavaScript in your own tab. It's never serialized into a network request. Nothing to log, nothing to scrub, no BAA required, because no third party ever receives the data.
Concretely, client-side validation means:
- Parsing the MSH/PID/OBX structure happens in your browser.
- Conformance checks (required segments, field cardinality, value-set membership) run against an in-browser rule engine.
- Scoring against a profile (for example US Core, once you've converted) is computed locally.
The only bytes that leave your machine are the page assets you already downloaded.
Validating a single message
For one message, you want depth: paste it, see the parsed segment tree, and get a list of structural and conformance issues with the exact field each one points at. This is the mode you use when debugging that one broken ADT^A01. You care about why field PID-8 is wrong, not just that something is.
A single-message view pairs naturally with mapping work. Validate the v2, then carry it through to FHIR and check both ends, as described in Mapping HL7v2 ADT^A01 to a US Core Patient.
Validating a batch
When you're regression-testing an interface or sanity-checking a vendor export, you have hundreds of messages, not one. Here you want breadth: a summary that tells you how many passed, how many failed, and the distribution of error types, then lets you drill into any single failing message for the detailed view above.
Doing this client-side has a second benefit beyond privacy. There's no upload size limit and no round-trip latency, so a folder of a few hundred messages validates as fast as your laptop can parse them.
What you give up (and what you don't)
Client-side validation can't reach a terminology server to expand every value set on demand, so extremely deep terminology binding may need a dedicated server. But for the day-to-day work (structure, cardinality, required fields, format, and profile coverage) everything you actually debug runs locally. And when you do need profile scoring, the same privacy model extends to FHIR: see US Core Patient: every required field and how it fails.
Validate safely
Paste a single HL7v2 message for a deep inspection, or drop a batch for a pass/fail summary. All of it is parsed in your browser, none of it uploaded.