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

verifaktura

v0.1.8

Published

EN 16931 e-invoice validation for UBL and CII, with national CIUS profiles (HR, RS/SEF, BA/FBiH) and localized rule messages.

Readme

verifaktura

npm licence

EN 16931 e-invoice validation for UBL 2.1 and CII D16B, with national CIUS profiles and rule messages in Croatian, Bosnian and Serbian.

Reference validators return [BR-02]-An Invoice shall have an Invoice number (BT-1). and an XPath. This returns a structured finding with the rule id, the business terms it concerns, a location and a message in the user's language — the difference between "something is wrong" and "add the invoice number".

npm install verifaktura
import { validate } from "verifaktura";

const report = await validate(xml, { lang: "hr" });

if (!report.valid) {
  for (const issue of report.issues) {
    console.log(issue.ruleId, issue.businessTerms, issue.message);
    // BR-02  ["BT-1"]  Račun mora sadržavati broj računa (BT-1).
  }
}

Command line: @verifaktura/cli.

Why not hard-coded rules

Validation rules change mid-mandate. The Croatian Tax Administration shipped a revised validator in March 2026, effective the 15th. Anyone who copied the rules into their own code went stale that day — and finds out when an invoice gets rejected.

verifaktura does not copy rules. It pulls the official artefacts (CEN/TC 434, Croatian Tax Administration) at build time, and CI warns when a new release appears.

National profiles

Profiles run after the base EN 16931 validation and are selected automatically from cbc:CustomizationID:

import { validate } from "verifaktura";
import "@verifaktura/cius-hr";   // registers the Croatian profile

const report = await validate(xml, { lang: "hr" });
// report.profiles -> [{ id: "en16931", ... }, { id: "hr", ... }]

| Profile | Package | Status | |---|---|---| | EN 16931 (UBL + CII) | built in | ✅ | | Croatia — Fiskalizacija 2.0 | @verifaktura/cius-hr | ✅ | | Serbia — SEF | @verifaktura/cius-rs | planned | | Bosnia and Herzegovina — FBiH | @verifaktura/cius-ba | pending regulations |

A national CIUS sometimes requires elements that CEN syntax rules forbid — the Croatian eRačun needs cbc:IssueTime, while UBL-CR-006 says it should not be there. A profile declares such rules through overrides: the finding stays in the report but drops to info with a note naming the profile that overrides it. Nothing is hidden, nothing cries wolf.

Report

{
  "reportVersion": "1.0",
  "valid": false,
  "document": { "syntax": "ubl", "type": "invoice", "id": "2026-001", "currency": "EUR", … },
  "profiles": [{ "id": "en16931", "version": "1.3.16", "source": "CEN/TC 434" }],
  "summary": { "fatal": 1, "warning": 0, "info": 0, "rulesFired": 211, "durationMs": 272 },
  "issues": [{
    "ruleId": "BR-02",
    "severity": "fatal",
    "profile": "en16931",
    "businessTerms": ["BT-1"],
    "location": { "xpath": "/*:Invoice[1]" },
    "message": "Račun mora sadržavati broj računa (BT-1).",
    "messages": { "en": "…", "hr": "…", "bs": "…", "sr": "…" }
  }]
}

businessTerms is deliberately a separate array — integrators map a finding onto a field in their own ERP through the BT number, without parsing text.

The format is versioned (reportVersion) and documented in FORMAT.md.

Generating invoices

The same model works in reverse. @verifaktura/build builds an invoice that verifaktura validates cleanly. VAT breakdown and totals are computed automatically, using integer arithmetic.

No JVM

Schematron runs through Saxon-JS as a precompiled SEF — no Java, plain Node. Roughly 250 ms for the first document (loading the stylesheet) and ~25 ms for each one after, since compiled stylesheets are cached in process.

Licence

The code is Apache-2.0.

This package ships precompiled CEN/TC 434 validation artefacts (sef/*.sef.json) which keep their own licence — EUPL 1.2. Attribution and details in NOTICE.