Skip to content

Repository files navigation

InvoML

Invoices as data. Totals you can trust. Output anywhere.

An open invoice format and TypeScript toolkit for portable, deterministic invoices.

Install | Quick start | Documentation | Contributing

npm next CI Node.js License

Why InvoML

Invoices should be easy to move between applications, safe to calculate, and readable by people as well as software. InvoML keeps authored facts in a compact JSON document and gives your runtime clear responsibilities for validation, arithmetic, and presentation.

  • Portable documents - store and exchange one JSON format across applications and services.
  • Deterministic totals - calculate with decimal arithmetic, currency-aware rounding, discounts, and tax categories instead of trusting pre-calculated model output.
  • Validation at the boundary - combine JSON Schema checks with invoice-specific domain rules.
  • Flexible output - render the same document as HTML, Markdown, or canonical JSON.
  • Presentation without lock-in - use locales, themes, templates, and renderer-neutral style tokens without putting raw CSS in the document.

InvoML is an alpha release. Install from the next npm tag while the format and APIs continue to evolve, and pin an exact version when reproducibility matters.

Installation

npm install invoml@next

InvoML supports Node.js 18 and newer and includes TypeScript declarations.

Quick start

Create an invoice from facts, validate it, calculate its totals, and render the result:

import { calculate, toHTML, validate, type InvoMLDocument } from 'invoml'

const invoice: InvoMLDocument = {
  $invoml: '1.0',
  meta: {
    documentType: 'invoice',
    number: 'EXAMPLE-001',
    issueDate: '2026-01-15',
    currency: 'USD',
  },
  items: [
    { description: 'Example item', quantity: 2, unitPrice: 750 },
  ],
}

const validation = validate(invoice)
if (!validation.valid) {
  throw new Error(validation.issues.map(issue => issue.message).join('\n'))
}

const calculated = { ...invoice, totals: calculate(invoice) }
console.log(calculated.totals?.total) // 1500
console.log(toHTML(calculated))

For untrusted serialized input, call parse() first. Use validateSchema() when the input is already a JavaScript value and you need schema validation without domain rules.

JSON input  ->  schema validation  ->  domain validation  ->  calculation  ->  output

Core API

Capability APIs
Parse and validate parse, validateSchema, setSchema, validate
Calculate calculate, CalculationError, currency-aware rounding helpers
Edit safely applyDiscount, removeDiscounts, applyTax, removeTax
Render toHTML, renderHTML, toMarkdown, renderMarkdown, toJSON
Present resolvePresentation, resolveStyle, resolveTheme, locale and date helpers

Focused subpath exports are available for the calculator, renderer, validator, mutators, formatting, themes, presentation, types, and the JSON Schema. The package also includes the invoml CLI.

CLI

Validate, calculate, or render a document from the command line:

npx invoml@next validate invoice.json
npx invoml@next calculate invoice.json
npx invoml@next html invoice.json > invoice.html

The html command accepts --theme <name> and --custom-css <file>.

Documentation

Security and data integrity

  • Parse untrusted serialized input, validate it, and only then calculate it.
  • Treat calculated totals as runtime output, never as authored source data.
  • Call setSchema() before validation in browser runtimes where filesystem access is unavailable.
  • Treat customCss as trusted runtime input; it is not an InvoML authoring surface.
  • Keep customer data, credentials, and private invoice details out of documents and source control.

See the security policy to report a vulnerability privately.

Contributing

Contributions are welcome. Read the contributing guide before opening a change. Include focused tests and update documentation or examples when behavior changes.

License

InvoML is available under the Apache-2.0 license.

About

Neutral invoice document markup and rendering contract

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages