Zero-based envelope budgeting in your terminal. Local-first, SQLite-backed, no fluff. Fast — every command should feel instant.
Every dollar has a job. Money flows from income into a Buffer, gets allocated to categories (envelopes), and is tracked as you spend. Balances are computed from an append-only ledger — never stored, never stale.
go install github.com/guygrigsby/oink@latestOr build from source:
make build # produces ./oink
make install # go installRequires Go 1.25+. No CGO — the SQLite driver is pure Go.
oink income 3000 # paycheck lands in Buffer
oink fund 500 groceries # allocate $500 to Groceries
oink spend 12.50 coffee shop dining # $12.50 from Dining Out
oink move 50 dining groceries # shift $50 between envelopes
oink status # see all balances
oink undo # reverse last action
oink category add Vacation # create a new envelope
oink category rm Vacation # remove an envelopeArguments are parsed naturally — filler words like "on", "for", "from", "to" are stripped automatically:
oink spend 20 on tacos for dining
oink fund 500 to groceries from paycheck
oink move 100 from dining to groceriesCategories are matched by case-insensitive prefix, so gro matches Groceries.
The database lives at ~/.oink/oink.db (or $XDG_DATA_HOME/oink/oink.db). It's created automatically on first run with 26 default budget categories.
The schema is 5NF-normalized with an append-only ledger. Undo doesn't delete — it appends reversing entries, preserving a full audit trail. See docs/schema.md for details.
cmd/ CLI layer (cobra commands, arg parsing, output)
↓
budget/ Business logic (fund, spend, move, undo)
↓
ledger/ Domain types & Ledger interface (zero dependencies)
↑
db/ SQLite implementation of Ledger
Business logic depends on the ledger.Ledger interface, not the concrete store. See docs/domain-model.md and docs/structure.md.
make testTests use in-memory SQLite for fast isolation.
MIT