One command, and the books are yours.
Postgres, migrations, the API, and the web UI come up in order, in the background. Your club's data never leaves the machine you run it on.
Start it.
git clone --recurse-submodules https://github.com/hatchertechnology/openbooks
cd openbooks
just run # postgres + api + web, in the background
just user-add you@example.com # prints a generated password, once
just seed # a club's worth of sample dataThen open http://localhost:38080 and sign in. There is no signup route on purpose: accounts are created from the command line, so nothing on the public internet can make one.
What you need.
- just
- Every task goes through the justfile at the repo root.
- Docker
- Postgres runs in a container; the ledger lives there.
- Rust (stable)
- The API, the desktop app, and the terminal client.
- Node 20+
- The web UI.
- jq
- Only needed for the end-to-end smoke check.
What it starts.
- http://localhost:38080
- web UI
- http://localhost:38081
- API
- localhost:38083
- Postgres
The servers run in the background, so nothing prints to your terminal;just logs follows both, andjust status says what is up. Usejust stop when you are done.
See it full before you commit to it.
just seed posts about 83 transactions across 2025 and the first half of 2026 — monthly dues and hall rent, bake sales and donations, field trips, insurance, and an invoice bought on credit and partly paid off, so the balance sheet has something under what we owe. Every month and quarter has activity and the amounts are deterministic, so reports are comparable between runs. Running it again replaces what it posted rather than doubling it.
just smoke is the one that matters: it posts real transactions, asserts the reported totals, and confirms the API rejects unbalanced and single-legged posts.
Worth knowing before you keep real books in it.
Authentication is required on everything except the health check — a session cookie for the web app, a bearer token for every other client, and passkeys if you would rather not type a password.
There is deliberately no role separation: any signed-in user can do anything any other can. For a household or a club committee that is usually the point, but it is a choice worth making knowingly.
Backups are yours to arrange. The ledger is one Postgres database; treat it the way you would treat the only copy of the club's accounts.
The full reference — routes, flags, ports, keybindings, and how the ledger model works — lives inthe documentation.