npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@einvoicekit/einvoicekit

v0.2.0

Published

Validate any EN 16931 e-invoice (Factur-X, ZUGFeRD, XRechnung, UBL, CII) against the full official rule set. One command, no key needed to start.

Readme

@einvoicekit/einvoicekit

Validate any EN 16931 e-invoice (Factur-X, ZUGFeRD, XRechnung, UBL or CII) against the full official rule set, from one command or one function call. No Java, no Saxon, no rule files to download.

npx @einvoicekit/einvoicekit invoice.pdf
invoice.pdf  INVALID  (cii, urn:cen.eu:en16931:2017)
  BR-CO-15  /Q{urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100}CrossIndustryInvoice[1]
            [BR-CO-15]-Invoice total amount with VAT (BT-112) = Invoice total amount without VAT (BT-109) + Invoice total VAT amount (BT-110).

Exit code 0 means every file is valid, 1 means at least one is not, 2 means at least one could not be validated. That is the whole integration for a CI pipeline.

What this package is, honestly

It is a thin client. Each call sends the invoice over HTTPS to einvoicekit's validator, which processes it in memory to produce the verdict and drops it; nothing is stored. What you get in exchange is the real thing: the official rule sets, EN 16931, XRechnung 3.0.2, Factur-X 1.09 and Peppol BIS 3.0, run by the reference validator, not a hand-written subset of them.

Two promises follow from that:

  • A verdict is a verdict. valid: false lists every broken rule with its official id, the official message and the XPath of the element at fault.
  • No silent green. If the service cannot be reached, you get an error, never valid: true. The package has no fallback and no retry; a retry policy is yours to write.

Install

npm install @einvoicekit/einvoicekit

Node 20 or later. No dependencies.

Renamed in 0.2.0: the package was @einvoicekit/facturx, the command facturx and the error class FacturxError. Nothing else changed.

Use it from code

import { readFile } from 'node:fs/promises';
import { validate, EinvoicekitError } from '@einvoicekit/einvoicekit';

const result = await validate(await readFile('invoice.pdf'));

result.valid; // true or false
result.errors; // [{ rule, message, path }, ...]
result.warnings; // same shape, never change the verdict
result.syntax; // 'cii' or 'ubl'
result.profile; // the profile URN the document declares, or null

validate(bytes, options?) takes a Uint8Array, an ArrayBuffer or a Blob: an XML invoice, or a Factur-X / ZUGFeRD PDF, which is unwrapped first so its embedded XML is what gets validated. The result is the API's JSON, field for field.

Options:

| option | meaning | | --------- | ------------------------------------------------------------------------------------------ | | apiKey | an einvoicekit key; defaults to EINVOICEKIT_API_KEY; with neither, the free pool is used | | target | 'france' adds the BR-FR rules French platforms apply, opt-in per call | | baseUrl | the API to call, default https://api.einvoicekit.com | | fetch | your own transport, default the global fetch | | signal | an AbortSignal |

Use it from the command line

npx @einvoicekit/einvoicekit invoice.pdf
npx @einvoicekit/einvoicekit a.xml b.pdf --target france
npx @einvoicekit/einvoicekit invoice.pdf --json
npx @einvoicekit/einvoicekit invoice.pdf --warnings
EINVOICEKIT_API_KEY=eik_live_... npx @einvoicekit/einvoicekit invoice.pdf

--json prints the API's verdict as JSON on stdout, an array when several files are given, and nothing else there; refusals go to stderr. --help lists every option.

Limits, plainly

  • Without a key: 10 validations a day per IP address, shared with the free tools on einvoicekit.com. The eleventh call is refused with the time the pool resets (midnight UTC) and a link to the free key.
  • With a free key: 100 validations a month, plus 20 generated invoices in an allowance of their own. No card. Get one by signing in with GitHub.
  • Pro: 29 € a month for 1,000 pooled credits, a validation spending one. Details.

Only a delivered verdict counts. A document the API cannot assess, a refused call and an error on the service's side cost nothing.

Errors

Everything that is not a verdict throws an EinvoicekitError with a stable code:

| code | HTTP | meaning | | --------------------- | ---- | ------------------------------------------------------------------------------- | | bad_request | 400 | the request itself was wrong (bad target, empty body) | | unauthorized | 401 | a key was sent and it is unknown, malformed or disabled | | too_large | 413 | over 5 MB | | unreadable_document | 422 | the API read the file and cannot assess it: a plain PDF, an unsupported profile | | pool_exhausted | 429 | the free daily pool is spent; resetsAt and upgrade say when and where | | rate_limited | 429 | too many calls in a short window; slow down | | quota_exceeded | 429 | the key's monthly allowance is spent; upgrade says where to get more | | service_unavailable | 5xx | the service answered but could not validate | | network | 0 | no response at all |

A wrong key is never a fallback into the free pool: send no key at all to use it.

Scope

Validation checks the invoice XML: the schema and every business rule of the profile the document declares. It does not check the PDF container's own PDF/A conformance; that check runs on the generation side of the API.

Full API documentation, the French rules and the generation endpoint: einvoicekit.com/docs.

Licence

MIT.