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

@financica/peppol

v0.3.0

Published

Peppol network toolkit for TypeScript: participant discovery via SML/SMP, Peppol Directory lookups, EAS schemes, and document-type classification.

Downloads

313

Readme

@financica/peppol

Peppol network toolkit for TypeScript. Provider-free participant discovery and reference data: check whether a company is reachable on the Peppol network, read the document types it accepts, enrich it from the public Peppol Directory, and resolve the right electronic address scheme (EAS) per country.

No API keys, no access point, no per-call cost — it talks to the public Peppol SML, SMP, and Directory directly.

npm install @financica/peppol

Participant reachability (SML → SMP)

Resolve a participant's SML NAPTR record to its SMP, then read the SMP's ServiceGroup to confirm registration and list the document types it can receive. Node only (uses node:crypto for the SML hash and node:dns for the NAPTR lookup).

import { lookupPeppolParticipant } from "@financica/peppol";

const result = await lookupPeppolParticipant({ scheme: "9925", value: "BE0123456789" });
// → { status: "registered", participantId: "9925:BE0123456789", documentTypes: ["invoice", "credit-note"] }
//   { status: "not_registered", participantId }
//   { status: "error", participantId, message }

// Pass `environment: "test"` to query the test SMK instead of production.

This targets the OpenPeppol-operated SML (…sml.prod.tech.peppol.org), which replaced the retired EC edelivery.tech.ec.europa.eu zone — and the modern NAPTR discovery that superseded the old CNAME scheme. A DNS name that doesn't exist (or carries no NAPTR) means the participant is not registered; any other DNS/transport failure returns status: "error" so callers can distinguish "absent" from "couldn't check".

Directory enrichment

The public Peppol Directory carries business-card data for participants who opted in. Best-effort only (not a source of truth for reachability):

import { buildCanonicalParticipantId, lookupPeppolDirectory } from "@financica/peppol";

const entry = await lookupPeppolDirectory(
	buildCanonicalParticipantId("9925", "BE0123456789"),
);
// → { name: "ACME NV", countryCode: "BE" } | null

EAS schemes by country

import {
	getPeppolCountryScheme,
	PEPPOL_COUNTRY_SCHEMES,
} from "@financica/peppol/schemes";

getPeppolCountryScheme("DE"); // → { country: "DE", scheme: "9930", example: "DE123456789" }

@financica/peppol/schemes, @financica/peppol/document-types, and @financica/peppol/countries are free of Node built-ins, so they are safe to import in a browser bundle (e.g. to build a country dropdown or label document types). The main entry pulls in the Node-only lookups.

Country e-invoicing profiles

Provider-neutral, hand-verified per-country facts for building an e-invoicing integration: the legal delivery network, the company and (separate, when one exists) VAT participant EAS schemes, where the VAT/registration number is validated (VIES vs BRREG), statutory archival years, and the org-number length to gate onboarding inputs on.

import { getCountryEInvoicingProfile } from "@financica/peppol/countries";

getCountryEInvoicingProfile("NO");
// → { network: "peppol", companyIdentifierScheme: "0192", vatIdentifierScheme: null, … }

A test pins these profiles to the addressing table in ./schemes so the two views cannot drift.

Document type classification

import { classifyPeppolDocumentType } from "@financica/peppol/document-types";

classifyPeppolDocumentType(rawBusdoxId); // → "invoice" | "credit-note" | "order" | … | "other"

document-types also exports the canonical BIS Billing 3.0, Self-Billing 3.0, and Invoice Response document type and process identifiers for registration payloads.

License

MIT