Measured, not claimed

Validation engines compared

Beleggo, Mustangproject, phive and 16 more engines compared

19 validation engines check the same 1,665 e-invoices from the Beleggo data kit — XRechnung, ZUGFeRD / Factur-X, Peppol BIS 3 and national CIUS, valid and defective — on the same machine, one document at a time. The official KoSIT validator runs alongside as the reference. Mustangproject and phive, the most widely used open-source validators, then stand next to Beleggo in detail.

Measured on 22 October 2026 on linux x64, Intel(R) Core(TM) Ultra 9 185H × 22, 62 GiB, Node v24.22.1

All 19 engines at a glance

EngineRuntimeLicenceProfilesCorrectFalse alarmsMissedRule namedMedianMemory
Beleggoartefacts 2026-08-31JavaScriptproprietaryall100%1,655 documents001,0865.7 ms962 MB
KoSIT Validator1.6.3 · Validator Configuration XRechnung 3.0.2 2026-09-02 · referenceJava 11+Apache-2.01 / 1198.6%285 documents004219.2 ms1,397 MB
core-invoice (Rust CLI)2.0.3RustMIT OR Apache-2.02 / 1190.3%874 documents33523412.6 ms33 MB
phive4.6.0Java 17+Apache-2.0all89.8%1,655 documents01609158.2 ms1,099 MB
dealerweb/einvoice1.1.0PHP 8MIT7 / 1188.3%1,176 documents313547928 ms152 MB
Mustangproject2.26.0Java 11+Apache-2.06 / 1184.8%1,067 documents1015243950 ms1,343 MB
en16931 (npm)0.1.0Node.jsMIT AND EUPL-1.21 / 1184.6%765 documents211339977 ms361 MB
@kontor-mcp/core1.0.4Node.jsApache-2.02 / 1184.2%1,050 documents015341080 ms660 MB
verifyhash-einvoice0.2.9Python 3Apache-2.02 / 1183.1%1,050 documents51724111.1 ms63 MB
verifaktura0.1.8Node.jsApache-2.02 / 1181.9%810 documents014742831 ms435 MB
EU ITB eInvoicing validator1.14.0-SNAPSHOT (2026-10-21) · CEN 1.3.16Java 17+EUPL-1.21 / 1181.3%765 documents0143417118 ms1,234 MB
@attestwire/en169310.14.0Node.jsMIT3 / 1180.2%1,159 documents122183752 ms223 MB
einvoice-kit0.1.3Node.jsMIT1 / 1180%765 documents11523630.3 ms189 MB
speedata/einvoicev0.0.22GoBSD-3-Clause3 / 1176.8%1,159 documents272423345 ms51 MB
stampbench (@stampbench/core)0.1.1Node.jsMIT2 / 1171.8%1,050 documents132832110.7 ms407 MB
en16931 (Rust CLI)0.6.0RustMIT OR Apache-2.03 / 1168.8%1,159 documents1442183212.8 ms23 MB
@fin.cx/einvoice11.1.1Node.jsMIT2 / 1159.9%1,050 documents253961065.1 ms383 MB
KoSIT Validator + ZUGFeRD configuration1.6.3 · Validator Configuration ZUGFeRD 2.5.2 2026-06-11 · referenceJava 11+Apache-2.04 / 1152.9%17 documents08634.7 ms975 MB
factur-x (akretion)6.8Python 3BSD-2-Clause4 / 1152.9%17 documents08140.5 ms69 MB

“Profiles”: how many of the kit’s 11 profiles the engine itself claims to check. “Correct”: the share of documents in those profiles whose verdict (valid or defective) matches the expected one; a document the engine cannot judge counts as wrong. As every engine covers different profiles, the percentages rest on different numbers of documents. The KoSIT validator is the official reference for XRechnung. Measured 22 – 23 October 2026.

“Rule named”: of the 1,086 defective samples across the kit, how many the engine rejects while naming the broken rule. “Median”: time per document after warm-up; “Memory”: peak of the whole process.

Not measured on the current kit, so not in the table: International.EInvoicing (.NET CLI): no .NET SDK on the machine that ran the bench (last measured 27 Sept 2026 over 722 documents); @aifind/mustangjs: no answer on a 1,000-line invoice (DK-790) within 15 minutes (last measured 27 Sept 2026 over 722 documents); Klarfakt: no .NET SDK on the machine that ran the bench (last measured 29 Sept 2026 over 722 documents); john-wink/en16931-php: its composer.lock does not install on the PHP of the machine that ran the bench (last measured 29 Sept 2026 over 722 documents); en16931 (Dart): no Dart SDK on the machine that ran the bench (last measured 29 Sept 2026 over 722 documents).

In detail: Beleggo, Mustangproject and phive

Correct verdicts

MeasureBeleggoMustangprojectphiveAhead
Correct verdicts, every documentagainst each sample’s expected verdict1,655 / 1,665 (99.4%)1,102 / 1,665 (66.2%)1,486 / 1,665 (89.2%)Beleggo
Correct verdicts in Mustang’s profilesonly the profiles Mustang itself checks1,067 / 1,077 (99.1%)905 / 1,077 (84%)902 / 1,077 (83.8%)Beleggo
Agreement with the KoSIT validatoron every XRechnung document — the scope the official validator is responsible for281 / 281 (100%)264 / 281 (94%)268 / 281 (95.4%)Beleggo
Defects named with the right rulenot just rejected, but the broken rule reported1,086 / 1,086 (100%)439 / 1,086 (40.4%)915 / 1,086 (84.3%)Beleggo
Profiles in the kit it checksformats whose own rules the engine knows11 / 116 / 1111 / 11Beleggo · phive

Speed and cost

MeasureBeleggoMustangprojectphiveAhead
Time per document (median)after warm-up5.7 ms50 ms8.2 msBeleggo
Time per document (95th percentile)the slow documents12 ms82 ms17 msBeleggo
Documents per secondone document at a time113.61674.1Beleggo
CPU time per documentall threads together12 ms124 ms37 msBeleggo
One-shot call (start + first document)what a command-line call costs187 ms3,541 ms4,322 msBeleggo
Memory (peak)of the whole process962 MB1,343 MB1,099 MBBeleggo
Install sizerules and runtime, without Node.js or Java56 MB56 MB58 MBBeleggo · Mustangproject

Beleggo runs the official Schematron rules as code translated to JavaScript, read from the same stylesheets Saxon-JS runs and checked against Saxon-JS as the reference on every test corpus: the same findings, the same text, the same order. A document the translated rules cannot judge exactly goes to Saxon-JS. CPU time is above the time per document because Node.js collects garbage on threads of its own. The same engine runs in the browser.

What each engine does

BeleggoMustangprojectphive
EN 16931 (UBL and CII)yesyesyes
XRechnung 3 with the official KoSIT severitiesyespartlypartly
Peppol BIS 3 and Peppol country rulesyesnoyes
NLCIUS, CIUS-RO, HR-CIUS, CIUS-PTyesnoyes
Factur-X / ZUGFeRD profiles (XSD and Schematron)yesyesyes
Visible PDF page checked against the XMLyesnono
Check digits (IBAN, VAT id, Leitweg-ID, tax number …)yesnono
Runs in the browser, no upload, no serveryesnono
Full PDF/A-3 validation (every rule of the veraPDF profiles)yesyesno
ZUGFeRD 1.0 and Order-Xyesyesno
French CTC rules (BR-FR Flux 2) as errors, in UBL and CIIyespartlyyes
XRechnung Schematron, current edition (2.6.0)yespartlyyes
Peppol BIS 3 in CIIyesnono
EXTENDED-CTC-FR and Flux 10 e-reporting (France)yespartlyyes
Every line recomputed (quantity × price)yesyesno
Warnings already announced as future errorsyesnono
Peppol PINT (EU, A-NZ, SG, JP, MY, AE, OM) — Beleggo in its CLI and MCP server, rules fetched from OpenPeppolyesnoyes
Peppol Invoice Response and Message Level Statusyesnoyes

Where and why they differ

Mustang departs from the expected verdict on 563 of 1,665 documents, 391 of them in profiles it does not check at all. The rest have five causes:

By profile

ProfileDocumentsBeleggoMustangprojectphive
en16931 · cii184184126121
en16931 · ubl419419340339
en16931 · zugferd162162162161
hr-cius · ubl4545545
nlcius · ubl2020919
peppol-bis3 · cii2211
peppol-bis3 · ubl10610656104
peppol-bis3 · zugferd1111
pt-cius · ubl302302101302
ro-cius · ubl11211224112
xrechnung · cii172167155159
xrechnung · ubl100959090
xrechnung · zugferd23232323
zugferd-basic · cii1111
zugferd-basic · zugferd3333
zugferd-basicwl · cii1100
zugferd-basicwl · zugferd3300
zugferd-extended · cii2222
zugferd-extended · zugferd3333
zugferd-minimum · cii1100
zugferd-minimum · zugferd3300

How it was measured

Data kit 0.1.0 (8c8d13d3eed69eec), 1,665 documents, judged against each sample’s expected verdict. That verdict comes from the Beleggo project; so that it confirms more than Beleggo, every Mustang disagreement was checked by hand against the specifications, and the official KoSIT validator runs alongside as an independent reference. Where it judges differently from Beleggo, it lacks the rule: the French CTC rules and one Factur-X code list.

Beleggo artefacts 2026-08-31, Mustangproject 2.26.0, phive 4.6.0 (with every phive-rules module; phive's own document detection picks the ruleset), KoSIT validator 1.6.3 · Validator Configuration XRechnung 3.0.2 2026-09-02. Each engine runs in its own process that lives for the whole measurement — so the times measure the engine, not a Java VM starting up.