Skip to content
Theo Brandt
All projects

Ledger

A double-entry accounting library with no opinions about your database.

Open source

2026

Ledger is a small library for double-entry bookkeeping. It does one thing: it holds a set of accounts and refuses to let them fall out of balance. It has no schema, no migrations, and no idea what a customer is.

I wrote it after the third time I watched a team reinvent accounting inside an invoicing feature, badly, with a single balance column that four different code paths were allowed to write to.

The design

Everything is an entry, entries come in transactions, and a transaction that does not sum to zero is rejected before it is stored. That single invariant removes an entire category of bug — the one where a refund succeeds, a ledger write fails, and nobody notices for six weeks.

  • No persistence layer — you hand it a repository interface and it does not care what is behind it
  • Balances are derived, never stored, with an optional checkpoint if you have millions of rows
  • Currency is a value object, and mixing two of them is a type error rather than a rounding error

What I learned

The hard part was not the arithmetic. It was resisting every request to add a feature that would have made the library know about invoices. Each one was reasonable in isolation, and each one would have made it useless for the next person.

It is used in production by four companies I know of and an unknown number I do not, which is exactly the right amount of contact to have with a library you maintain in the evenings.

Say hello

I read everything and reply to most of it. Notes about something I wrote are especially welcome, particularly the ones telling me I am wrong.

[email protected]