The missing EN 16931 toolkit for JavaScript
Every serious EN 16931 implementation used to be Java or Python. einvoice brings parsing, validation and rendering of EU e-invoices to the npm ecosystem — zero dependencies, typed end to end, running in Node ≥ 18, browsers and edge runtimes.
- MIT license
- 0 dependencies
- ~165 EN 16931 rules
- UBL · CII · Factur-X · XRechnung · Peppol
- Node · browser · edge
Library
npm install einvoice
import { parseInvoice, validate, renderText } from "einvoice-kit";
// UBL XML, CII XML, or a Factur-X/ZUGFeRD PDF — auto-detected
const { invoice, format, profile } = await parseInvoice(bytes);
const result = validate(invoice); // EN 16931 business rules
if (!result.ok) {
for (const f of result.findings) {
console.log(f.rule, f.where ?? "", f.hint ?? f.text);
}
}
console.log(invoice.totals.payable?.raw); // typed semantic model (BT-115)
console.log(renderText(invoice)); // human-readable summary
The parser is namespace-aware and immune to XXE by construction (no DOCTYPE, no entity expansion). All rule arithmetic uses exact BigInt decimals — no floating-point VAT surprises. Amounts keep their lexical form, so decimal-precision rules (BR-DEC) behave exactly like the official Schematron.
CLI
npx einvoice-kit validate invoice.xml # exit 1 on violations — CI-friendly
npx einvoice-kit validate --json *.xml # machine-readable findings
npx einvoice-kit show facture.pdf # readable summary of a Factur-X PDF
npx einvoice-kit inspect invoice.xml # full semantic model as JSON
MCP server (AI agents)
Give any MCP-capable agent the ability to read and validate e-invoices locally:
{
"mcpServers": {
"einvoice": { "command": "npx", "args": ["-y", "einvoice-kit-mcp"] }
}
}
Tools: validate_invoice and read_invoice — both accept XML content or a file path, including Factur-X PDFs. Invoice data never leaves the machine.
What's implemented
| Area | Status |
|---|---|
| UBL 2.1 Invoice & CreditNote → semantic model | ✅ full BT/BG mapping |
| UN/CEFACT CII (D16B) → semantic model | ✅ full BT/BG mapping |
| Factur-X / ZUGFeRD PDF extraction | ✅ incl. PDF 2.0 / PDF-A/4, Flate streams |
| EN 16931 business rules (BR, BR-CO, BR-DEC, VAT groups, BR-CL) | ✅ ~165 rules, official ±1 tolerances |
| Rendering (text, standalone HTML) | ✅ |
| XRechnung BR-DE / Peppol national rules | 🔜 roadmap |
| Invoice generation (model → XML) | 🔜 roadmap |
Verification: the engine runs against 120 official test files from the EU and KoSIT corpora in CI — see the conformance report. Schema (XSD) validation is intentionally out of scope for v0.x; the semantic rules catch what matters for interoperability.
Why not wrap the official Schematron?
Running the official XSLT needs Java (or SaxonJS) and yields messages like "[BR-CO-15] failed". A native rule engine over one semantic model validates both syntaxes with the same code, runs in ~1 ms per invoice, fits in a browser tab, and can tell you "BT-112 is 336.90, expected 366.86 = 314.86 + 52.00". The official artefacts remain our reference: rule texts, code lists and tolerances are extracted from them mechanically, and the corpus keeps us honest.