Measured, not claimed

Validation engines compared

Beleggo, Mustangproject, phive and 21 more engines compared

24 validation engines check the same 722 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 30 September 2026 on linux x64, Intel(R) Xeon(R) Processor @ 2.10GHz × 4, 16 GiB, Node v22.22.2

All 24 engines at a glance

EngineRuntimeLicenceProfilesCorrectFalse alarmsMissedRule namedMedianMemory
Beleggoartefacts 2026-08-31JavaScriptproprietaryall100%722 documents003385 ms329 MB
dealerweb/einvoice1.1.0PHP 8MIT7 / 1198.7%697 documents1828946 ms149 MB
EU ITB eInvoicing validator1.14.0-SNAPSHOT (2026-09-25) · CEN 1.3.16Java 17+EUPL-1.21 / 1198%449 documents0927392 ms682 MB
KoSIT Validator1.6.3 · Validator Configuration XRechnung 3.0.2 2026-09-02 · referenceJava 11+Apache-2.01 / 1197.9%187 documents0028211 ms1,021 MB
verifaktura0.1.8Node.jsApache-2.02 / 1197.6%455 documents01125152 ms392 MB
einvoice-kit0.1.3Node.jsMIT1 / 1197.3%449 documents0122301.2 ms100 MB
phive4.6.0Java 17+Apache-2.0all96.7%722 documents0223117.4 ms867 MB
en16931 (npm)0.1.0Node.jsMIT AND EUPL-1.21 / 1196.7%449 documents11125555 ms239 MB
Klarfakt1.0.0-preview.2.NET 10BUSL-1.1 (free for evaluation; Apache-2.0 after four years)3 / 1196.4%687 documents81727811 ms463 MB
@kontor-mcp/core1.0.4Node.jsApache-2.02 / 1195.9%636 documents019277195 ms507 MB
Mustangproject2.26.0Java 11+Apache-2.06 / 1195.4%646 documents72328144 ms955 MB
@aifind/mustangjs0.4.0Node.jsApache-2.02 / 1194%636 documents82426573 ms407 MB
core-invoice (Rust CLI)2.0.3RustMIT OR Apache-2.02 / 1194%500 documents10202182.7 ms10 MB
verifyhash-einvoice0.2.9Python 3Apache-2.02 / 1193.6%636 documents4372522.1 ms28 MB
International.EInvoicing (.NET CLI)1.1.0.NET 8+MIT2 / 1193.4%636 documents431259320 ms193 MB
john-wink/en16931-php0.3.0PHP 8MIT2 / 1193.1%636 documents14324236 ms51 MB
@attestwire/en169310.14.0Node.jsMIT3 / 1190.5%687 documents7582282.3 ms110 MB
en16931 (Dart)0.1.4Dart, AOT-compiledMIT7 / 1189%697 documents20572261 ms48 MB
speedata/einvoicev0.0.22GoBSD-3-Clause3 / 1188.9%687 documents15612087.4 ms17 MB
stampbench (@stampbench/core)0.1.1Node.jsMIT2 / 1184.9%636 documents8881541.5 ms83 MB
en16931 (Rust CLI)0.6.0RustMIT OR Apache-2.03 / 1176.4%687 documents116461943.1 ms10 MB
@fin.cx/einvoice11.1.1Node.jsMIT2 / 1169.5%636 documents14180579.4 ms161 MB
KoSIT Validator + ZUGFeRD configuration1.6.3 · Validator Configuration ZUGFeRD 2.5.2 2026-06-11 · referenceJava 11+Apache-2.04 / 1150%10 documents05315.7 ms831 MB
factur-x (akretion)6.8Python 3BSD-2-Clause4 / 1150%10 documents05140.4 ms45 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 25 – 30 September 2026.

“Rule named”: of the 338 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.

In detail: Beleggo, Mustangproject and phive

Correct verdicts

MeasureBeleggoMustangprojectphiveAhead
Correct verdicts, every documentagainst each sample’s expected verdict722 / 722 (100%)668 / 722 (92.5%)698 / 722 (96.7%)Beleggo
Correct verdicts in Mustang’s profilesonly the profiles Mustang itself checks646 / 646 (100%)616 / 646 (95.4%)623 / 646 (96.4%)Beleggo
Agreement with the KoSIT validatoron every XRechnung document — the scope the official validator is responsible for183 / 183 (100%)167 / 183 (91.3%)175 / 183 (95.6%)Beleggo
Defects named with the right rulenot just rejected, but the broken rule reported338 / 338 (100%)281 / 338 (83.1%)311 / 338 (92%)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 ms44 ms7.4 msBeleggo
Time per document (95th percentile)the slow documents20 ms88 ms25 msBeleggo
Documents per secondone document at a time11217.256.8Beleggo
CPU time per documentall threads together13 ms118 ms48 msBeleggo
One-shot call (start + first document)what a command-line call costs345 ms3,822 ms5,325 msBeleggo
Memory (peak)of the whole process329 MB955 MB867 MBBeleggo
Install sizerules and runtime, without Node.js or Java15 MB56 MB58 MBBeleggo

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 54 of 722 documents, 24 of them in profiles it does not check at all. The rest have five causes:

By profile

ProfileDocumentsBeleggoMustangprojectphive
en16931 · cii49494445
en16931 · ubl264264260259
en16931 · zugferd136136136135
hr-cius · ubl6626
nlcius · ubl5545
peppol-bis3 · cii1111
peppol-bis3 · ubl49493748
peppol-bis3 · zugferd1111
pt-cius · ubl5535
ro-cius · ubl9949
xrechnung · cii126126114119
xrechnung · ubl47474346
xrechnung · zugferd14141414
zugferd-basic · cii1111
zugferd-basic · zugferd2222
zugferd-basicwl · cii1100
zugferd-basicwl · zugferd1100
zugferd-extended · cii1111
zugferd-extended · zugferd1111
zugferd-minimum · cii1100
zugferd-minimum · zugferd2200

How it was measured

Data kit 0.1.0 (969f6f3ec8fdccbc), 722 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.