Open-source invoicing you host yourself: quotes, invoices, payments and the paperwork that follows — including the e-invoicing rules of the country you bill from.
- Quotes, invoices, credit notes, purchase orders, goods receipts, expenses and received invoices — one document engine, one lifecycle, one list and detail screen for every type.
- Payments, partial payments, deposits, instalments and settlement badges computed from the record, never stored on the document.
- Clients with their own portal, account statements and aged balance.
- An article catalogue with stock counts, project time tracking that turns into invoice lines, and recurring documents.
- Bank statement import (CSV/OFX) with reference and amount matching, plus online payment methods.
- PDF generation, e-invoice XML (Factur-X, UBL, CII, XRechnung, Peppol BIS, FatturaPA, FA(3)) and national transmission channels.
- A legal archive per issued document, with the retention duration and its starting point taken from the country's own rule.
- Encrypted, scheduled backups of every archived document and uploaded file to a separate bucket, with a key the storage provider never holds.
- Sign-in by e-mail/password, OIDC/SSO (instance-wide or per company) or API key; multi-company, role-based access; webhooks, a REST API, an MCP server and a plugin system.
- 18 interface languages, per-recipient document language, multi-currency with rate history.
- Installable as a PWA, light and dark themes.
Invoicing
Invoice list, filtered by status, with the settlement state of each one.
Creation wizard — lines filled from the article catalogue, VAT rates from the seller country's own rate list.
Invoice detail: totals, settlement and the legal archive with its retention rule.
Quotes, convertible to invoices, with deposit and instalment requests.
Credit notes correct an invoice line by line, never freehand.
Purchasing
Purchase orders sent to suppliers.
Received invoices — uploaded, OCR-read into an editable proposal, then approved or rejected.
Clients
Client list with activity and supplier filters.
Account statement: every document, the balance and the aged balance.
The client portal — the client's own documents, balance, PDFs, payment and quote decisions.
Quote signing: a one-time code sent to the signer, then a signed quote.
Catalogue and time
Articles priced per hour, day, unit or service, with stock counts and low-stock alerts.
Time tracking per project, billable or not, turned into invoice lines in one step.
Getting paid
Bank reconciliation: import a statement, confirm the suggested match, get a real payment record.
Payment methods offered to clients, with the details each one shows on the document.
Settings
Company settings — the country decides which identifiers are asked for, and how they are labelled.
E-invoicing channels: connect the national platform the country expects, then use it as the invoice transport.
Signing certificates for PAdES-signed PDFs.
E-mail templates, one per document type plus the system e-mails.
A country is data, not code: which actions a document allows, which identifiers a party must supply, which correction route applies, which VAT rates exist, which channel and format a buyer requires, how long an archive must be kept — each is its own catalogue of sourced facts, and every fact carries the legal text it comes from.
Germany, France, Italy, Poland and Portugal ship with their catalogues filled in.
| Channel | Country | Used for |
|---|---|---|
| PDP | France | B2B e-invoicing through an accredited platform |
| Chorus Pro | France | B2G invoices to public buyers |
| KSeF | Poland | National clearance |
| SdI | Italy | National clearance (web service) |
| SdI over PEC | Italy | National clearance (certified e-mail) |
| Any | PDF and attached e-invoice XML |
The full per-country picture is generated from those data files on every documentation build: country support matrix · adding a country.
A prebuilt image is published at ghcr.io/invoicerr-app/invoicerr,
built for linux/amd64 and linux/arm64. linux/arm/v7 (32-bit ARM) is no longer built: Node.js
stopped publishing linux-armv7l binaries starting with Node 24. See the
Docker installation guide for the
64-bit alternative on the same hardware.
-
Create a
docker-compose.yml:services: invoicerr: image: ghcr.io/invoicerr-app/invoicerr:latest ports: - "80:80" volumes: # Legal archives and received invoices. Without it they live in the container's writable # layer and are destroyed by the next image pull. - documents_data:/data environment: - DATABASE_URL=postgresql://invoicerr:${POSTGRES_PASSWORD:?set it in a .env file next to this one}@invoicerr_db:5432/invoicerr_db - APP_URL=https://invoicerr.example.com - DOCUMENTS_ARCHIVE_DIR=/data/documents-archive - DOCUMENTS_INBOUND_DIR=/data/documents-inbound # Signs every session cookie. Generate with: openssl rand -hex 32 - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:?set it in a .env file next to this one} # Redis is required for the backend to boot at all (the document-action queue). - REDIS_HOST=redis - REDIS_PORT=6379 # One mail provider, or nothing can be sent. Resend is the alternative: # MAIL_PROVIDER=resend + RESEND_API_KEY. - SMTP_HOST=smtp.example.com - SMTP_USER=invoices@example.com - SMTP_PASSWORD=${SMTP_PASSWORD:?set it in a .env file next to this one} - SMTP_PORT=587 - SMTP_SECURE=false depends_on: - invoicerr_db - redis invoicerr_db: image: postgres:15 environment: POSTGRES_USER: invoicerr # Postgres applies this only on first init of an empty volume. POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set it in a .env file next to this one} POSTGRES_DB: invoicerr_db volumes: - db_data:/var/lib/postgresql/data redis: image: bitnami/redis:latest restart: unless-stopped environment: ALLOW_EMPTY_PASSWORD: "yes" volumes: - redis_data:/bitnami volumes: documents_data: db_data: redis_data:
-
Put the three secrets (
POSTGRES_PASSWORD,BETTER_AUTH_SECRET,SMTP_PASSWORD) in a.envfile next to it, then start:docker compose up -d
-
Open
http://localhostand create the first account.
The reference compose file with every option — OIDC, OCR, mail providers — is
docker-compose.yml; docker-compose.scale.yml
adds dedicated queue workers. Every variable is documented, with its default and the source file that
default lives in, in backend/.env.example.
For more than one host, use the Helm chart in deploy/helm/invoicerr/. The
API and worker scale safely as independent Deployments — three API replicas behind a load balancer and
fifteen workers — once the legal archive and uploaded files move to S3-compatible object storage
instead of local disk, which is what makes running on more than one machine possible at all. The
Kubernetes guide's own reference deployment
runs entirely on one French provider, in Paris: cluster, object storage and managed database.
docker compose pull && docker compose up -dDatabase migrations run at boot, in the API role only. When a release changes which countries the shipped catalogues cover, one manual step follows it, because no boot path is allowed to delete a country's rows:
npm run catalogs:release # from the backend workspace — /usr/share/nginx/backend in the image| Page | What it covers |
|---|---|
| Introduction | What Invoicerr is, and the first steps in it |
| Docker installation | The full compose reference and every environment variable |
| Kubernetes deployment | The Helm chart, its two roles, storage and ingress |
| Instance backups | Encrypted backups to a separate bucket, and how to restore one |
| User guide | Every screen: documents, clients, portal, settings |
| Developer guide | Architecture, document types, catalogues, local setup |
| API reference | The REST API and its authentication |
| Plugins · Webhooks · MCP server | Extending Invoicerr from outside |
| Live testing | Running the real round-trips against national platforms |
| Changelog | Every release |
| Area | Stack |
|---|---|
| Backend | NestJS 12, TypeScript 5.7, Swagger/OpenAPI |
| Database | PostgreSQL (Prisma 7 — no other engine: the schema hardcodes the postgres provider) |
| Queue | BullMQ 5 on Redis (required to boot; inline worker or dedicated processes) |
| Auth | better-auth 1.7 — e-mail/password, OIDC/SSO, API keys |
| Frontend | React 19, Vite 7, TanStack Query 5, Tailwind CSS 4, Radix UI (shadcn-style), react-i18next |
playwright-core 1.63 (headless Chromium), pdf-lib, @signpdf for PAdES |
|
| E-invoice XML | @e-invoice-eu/core, @digitalia/fatturapa, node-schematron, xmllint-wasm |
| OCR | ghcr.io/invoicerr-app/ocr-image — ocrmypdf + Tesseract, self-hosted, opt-in |
| Tests | Vitest (backend and frontend), Cypress 15 (end-to-end and per-country scenarios) |
| Tooling | Biome 2.5 (lint and format), Docker, Helm 3, GitHub Actions |
| Documentation | Docusaurus 3.10 |
| Hosted billing | Polar (hidden unless the instance explicitly enables it; self-hosting stays free) |
Issues and pull requests are welcome — see CONTRIBUTING.md for how to report a
bug, propose a feature, and get a pull request merged. Setting the four workspaces up, running the test
stack and running the end-to-end suites are covered in
local development; how the
pieces fit together is in architecture.
Translations are managed on Weblate; the English catalogue in frontend/src/locales/en is the source
every other language is translated from.
Invoicerr is free and open source, maintained in spare time. If it saves you time or money, consider supporting its development through GitHub Sponsors.
Maintainer: Roméo Chevrier (@Impre-visible).
With contributions from Quentin Marques, Guillaume Ouint, Luís Rodrigues, Ruben Dorozala, Guillaume Aubert, Jonas Ghyllebert, Dmitry Warkentin, Fabio Orlandi, Mike Meijndert, Victor Fernandez, Tom Ruff, T13o, javlk, MakoPhil, anasdwc, nlimeres and richipargo, plus everyone who has translated the interface on Weblate.
Private vulnerability reporting is enabled: open a security advisory rather than a public issue. Please do not report a vulnerability in an issue, a pull request or a discussion.
The paths between the API's routes and the database tables are also checked by
Wyro, a free and independent architecture scanner.
Its report is public: as of September 2026 it finds no error, and its remaining notes list the routes
that are public on purpose (token-gated document and signature links, the SSO lookup and
registration). Wyro reports a real vulnerability to the maintainers privately before anything shows
on that page, as set out in its security policy. It complements our
own reviews and tests; it does not replace them. wyro.json at the root holds its configuration.
Issues for bugs and feature requests, Discussions for questions and ideas, Discord to chat with users, self-hosters and contributors.
AGPL-3.0 — free for any use, commercial included. If you run a modified version as a network service, you offer its source to the people using it (section 13). That is the whole deal; there is no second licence and no paid tier of the software itself.




















