Invoice Ninja

invoiceninja.comcontributed by Samuele Ongaro

YES

Replaceable in one session with an AI coding agent.

Invoicing, quotes, expenses and payments for freelancers and small firms, with a hosted plan and a self-hosted version of the same application.

Promptfree, for everyone, and the only version there is
Build me the invoicing I actually need instead of a hosted Invoice Ninja: quotes, invoices, expenses and payments, with a portal my clients can use.

Read this first: Invoice Ninja is open source and self-hosting it is a real answer. What the fee buys is dozens of payment gateways already onboarded and templates that satisfy different countries' invoicing rules. Build this when you invoice in one country, in one or two currencies, through one payment provider — which is most freelancers and small firms.

STACK
- Node 20+ with Fastify, server-rendered HTML
- SQLite through better-sqlite3, WAL mode
- PDF from HTML with a paged-CSS renderer
- One payment provider, hosted checkout, so no card ever touches this application
- Caddy in front

THE DATA MODEL
- businesses: id, name, address, tax_id, vat_number, iban, logo_path, default_currency, default_terms, invoice_prefix
- clients: id, business_id, name, address, tax_id, vat_number, currency, payment_terms_days, portal_token, archived_at
- contacts: id, client_id, name, email, is_primary — a client is a company and has people
- quotes: id, client_id, number, issued_on, valid_until, status, total_cents, converted_invoice_id
- invoices: id, client_id, number, issued_on, due_on, currency, exchange_rate, status, subtotal_cents, tax_cents, total_cents, paid_cents, notes, terms, pdf_path, pdf_hash, sent_at, viewed_at, paid_at, voided_at, void_reason, recurring_id
- lines: id, parent_kind, parent_id, position, description, quantity, unit_price_cents, tax_rate, discount_percent
- expenses: id, business_id, client_id, category, amount_cents, currency, incurred_on, receipt_path, is_billable, markup_percent, invoice_id
- payments: id, invoice_id, amount_cents, currency, paid_on, method, reference, external_id
- number_sequences: business_id, kind, year, last_number
- Amounts in integer cents with a currency. Never a float

NUMBERING AND IMMUTABILITY, WHICH ARE LEGAL RATHER THAN AESTHETIC
- Sequential with no gaps, per business, per document kind, per year, allocated inside the transaction that issues the document
- A draft has no number; the number is taken at issue
- An issued invoice is never edited and never deleted. A mistake is voided with a reason and corrected by a credit note that references it
- A credit note is an invoice with negative lines and its own sequence
- The rules differ by country. State the assumptions in the README and make the format configurable

TAX
- Per-line rates, with totals broken out by rate — most authorities require the breakdown
- Reverse charge for cross-border business customers, with the required sentence printed and both VAT numbers shown
- Zero-rated and exempt stored as different things
- The rate is copied onto the line at issue. Changing a rate later must never alter a document already issued

QUOTES
- Same shape as an invoice, with an expiry
- The client accepts or declines from the portal, with the acceptance recorded — who, when, from where
- Accepting converts to an invoice, keeping the link between them

RECURRING
- A template plus a cadence; a worker issues the next one and emails it
- Idempotent, so the worker can run twice without issuing twice
- Pause and resume without renumbering anything
- Automatic charging where the provider holds a mandate, with a failure path that emails rather than retries silently

THE CLIENT PORTAL
- A long unguessable token per client — no account, no password. Requiring a login is how an invoice goes unpaid for a fortnight
- Shows every document, its status, the balance, and a pay button
- Downloads the PDF, accepts a quote, and shows the payment history
- Optionally a password on top for clients who ask for one

GETTING PAID
- Hosted checkout from the provider; this application stores no card data and is therefore out of scope for the hardest compliance
- Webhooks with signature verification, idempotency by event id, and out-of-order handling
- Partial payments recorded with the balance derived; status is never typed
- Reminders before and after the due date on a schedule, each recorded so nobody is chased twice in a day
- A late fee rule, applied deliberately and visibly, never silently

MULTI-CURRENCY
- The invoice currency is the client's; the books are in the business's
- The exchange rate and its date recorded on the invoice, and never re-derived afterwards

EXPORT
- Every document as PDF and every row as CSV or JSON, per period, in one command
- A report by client, by month, by tax rate, and an aged-debtors list — which is the report that gets you paid

OPERATIONS
- .env: DATABASE_PATH, STORAGE_PATH, BASE_URL, SMTP_URL, SESSION_SECRET, PROVIDER_KEY, PROVIDER_WEBHOOK_SECRET
- Migrations on boot, each once
- Nightly backup covering the database and the PDF store, with a tested restore
- Health endpoint

WHAT MATTERS MOST
Numbering, immutability and the portal token. Build the sequence allocation and the stored PDF first and try to break them — two invoices issued in the same instant, a void, a year boundary. Then make paying take two clicks from an email, because every extra step is a week of delay.

Give me the repository, migrations, .env.example, a seed business with clients and documents, and a README with deploy steps behind Caddy and a note to check the numbering rules with a local accountant.

What you lose

  • Connections to dozens of payment gateways, each with its own onboarding, already built
  • Invoice templates that satisfy the numbering and content rules different countries require
  • A client portal where a customer can see and pay everything they owe

If you would rather not build

  • Stripe Invoicing, if you already use Stripe

What it costs

as published on their pricing page

PlanBilled monthlyBilled yearlyLast read
—$12/mo——

Their pricing page is where these came from. Seeing a different price? Tell us.

The escape hatch

open source · no votes, no paid placement

Invoice Ninja

$0

The product itself, self-hostable.

invoiceninja/invoiceninjafree · open source

Crater

$0

A lighter open-source invoicing app with a client portal.

crater-invoice-inc/craterfree · open source

Why this verdict

our own opinion · changed only by a person

79/100

Verdict yes at 79. Invoicing is a well-understood build; gapless numbering and immutable issued documents are the two things to get right.

History

tracked since 10 Aug 2026 · nothing is ever overwritten

Interest · last 30 dayspeak 3/day
views012330 Aug4 Sept9 Sept14 Sept19 Sept24 Sept28 Sept
— views— prompt copies none yet— votes none yet

Questions about Invoice Ninja

answered from the record above

Is Invoice Ninja free?

No — the plan we track is $12 a month. Pro at $12/month billed monthly, $10 annually; the software is also free to self-host.

Can you replace Invoice Ninja by building your own?

YES. Replaceable in one session with an AI coding agent. Replacement score 79 out of 100, build time one session. Read what you lose before you decide.

How much does Invoice Ninja cost?

$12 a month on Pro — $144 a year. Recorded 10 Aug 2026.

What do you lose by replacing Invoice Ninja?

Connections to dozens of payment gateways, each with its own onboarding, already built; Invoice templates that satisfy the numbering and content rules different countries require; A client portal where a customer can see and pay everything they owe. If any of those carry weight for you, keep paying.

Is there an open-source alternative to Invoice Ninja?

Yes: Invoice Ninja, Crater. The prompt on this page is for when you want it your way instead.

Related entries

same category first, most replaced first

All 18 in Time tracking & invoicing

Not sending yet

Every week, something stops being worth paying for.

New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.

free forever · no tracking pixel · stored here, never passed to anyone

Esc