Profile
Back to NewsBack
GitHub Trending 9 min
Reader Mode
invoicerr-app/invoicerr: Invoicerr is a freelance-focused invoicing app that lets you create quotes, generate invoices, track payments, and collect secure signatures.

invoicerr-app/invoicerr: Invoicerr is a freelance-focused invoicing app that lets you create quotes, generate invoices, track payments, and collect secure signatures.

15 hours ago

!Invoicerr

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.

Tests</a> Latest release</a> Container image</a> License</a>

!Dashboard

What you get

  • 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.

Screenshots

Invoicing

Invoice list, filtered by status, with the settlement state of each one.

!Invoice list

Creation wizard — lines filled from the article catalogue, VAT rates from the seller country's own rate list.

!Invoice creation wizard

Invoice detail: totals, settlement and the legal archive with its retention rule.

!Invoice detail

Quotes, convertible to invoices, with deposit and instalment requests.

!Quotes

Credit notes correct an invoice line by line, never freehand.

!Credit note

Purchasing

Purchase orders sent to suppliers.

!Purchase orders

Received invoices — uploaded, OCR-read into an editable proposal, then approved or rejected.

!Received invoices

Clients

Client list with activity and supplier filters.

!Clients

Account statement: every document, the balance and the aged balance.

!Client statement

The client portal — the client's own documents, balance, PDFs, payment and quote decisions.

!Client portal

Quote signing: a one-time code sent to the signer, then a signed quote.

!Quote signature

Catalogue and time

Articles priced per hour, day, unit or service, with stock counts and low-stock alerts.

!Articles

Time tracking per project, billable or not, turned into invoice lines in one step.

!Time tracking

Getting paid

Bank reconciliation: import a statement, confirm the suggested match, get a real payment record.

!Bank reconciliation

Payment methods offered to clients, with the details each one shows on the document.

!Payment methods

Settings

Company settings — the country decides which identifiers are asked for, and how they are labelled.

!Company settings

E-invoicing channels: connect the national platform the country expects, then use it as the invoice transport.

!E-invoicing channels

Signing certificates for PAdES-signed PDFs.

!Signing certificates

E-mail templates, one per document type plus the system e-mails.

!E-mail templates

Dark theme

!Dashboard in dark theme

Country coverage

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) | | 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.

Quick start

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.

  1. 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
         - [email protected]
         - 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:

  1. Put the three secrets (POSTGRES_PASSWORD, BETTER_AUTH_SECRET, SMTP_PASSWORD) in a .env
file next to it, then start:
docker compose up -d
  1. Open http://localhost and 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.

Updating

docker compose pull && docker compose up -d

Database 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

Documentation

docs.invoicerr.app

| 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 |

Technologies

| 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 | | PDF | 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) |

Contributing

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.

Translation status</a>

Support the project

Invoicerr is free and open source, maintained in spare time. If it saves you time or money, consider supporting its development through GitHub Sponsors.

Sponsors</a>

Contributors

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.

Security

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.

Community

Issues for bugs and feature requests, Discussions for questions and ideas, Discord to chat with users, self-hosters and contributors.

Discord</a>

License

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.

Chat with me