Skip to content

Latest commit

 

History

562 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Balances

Track your household's net worth without itemising a single transaction.

Each month you enter your balances; Balances tracks your net worth over time.

Live demo · Self-hosting · The domain model

CI License: AGPL-3.0


What it is

Most personal-finance apps make you record every coffee. Balances doesn't. It's built on a single ritual: at the end of each month, you read the balances off your statements and type them in. From those snapshots it computes your household net worth over time — no bank sync, no transaction feed, no categorising.

That one design choice is deliberate (ADR-0001). Itemised cash-flow tracking (Mint / YNAB style) is a non-feature. If you've bounced off budgeting apps because the daily upkeep never stuck, this is the opposite bargain: ten minutes a month, and you still get the one number that matters.

Why it's different

  • Household-first, not person-first. Every position, snapshot, and income event belongs to a Household — the people sharing economic life. Multiple members, one shared picture of net worth, with per-member and Joint breakdowns. No app in this niche is built household-first.
  • Snapshot-first, not sync-first. You own the numbers. Nothing is scraped from your bank; nothing leaves your control. The month-end reading is the source of truth.
  • Real coverage for the instruments people actually hold — bank accounts, property, and vehicles; stocks, mutual funds, and gold by the gram; bonds and time deposits with coupons and maturity. It handles Indonesian retail instruments most apps ignore outright — ORI/SBR/SR/ST government bonds and deposito — alongside everything else.
  • Multi-currency when you need it, invisible when you don't. Hold a foreign account and the currency pickers and FX entry appear; otherwise the whole surface stays pinned to your reporting currency.
  • The residual-expense insight, for free. Because net worth, earned income, and investment returns are all tracked, the app derives what you spent last month as a single residual number — without you logging a single expense.

What you get

  • Net worth over time, per-Household and broken down per member and by household-defined Tags (by goal, by bank, by risk — you decide).
  • An income statement and a cash-spending proxy, both derived from the same snapshots.
  • A transaction ledger only where it earns its keep — investment instruments — for cost basis and income reporting. Everything else is just the monthly balance.
  • Spreadsheet import for backfilling history, and a full-fidelity backup/restore that moves an entire Household between instances (SaaS ↔ self-host, either direction).
  • English and Indonesian throughout.

Try it

  • Hosted demohttps://balances-demo.fly.dev. A shared, resets-nightly instance; poke at it without signing up for anything.
  • Self-host it — one docker-compose.yml, a published image, Postgres, done. See Self-hosting below.

Self-hosting

The repo-root docker-compose.yml is the operator stack (ADR-0037): it pulls the published image ghcr.io/kerti/balances:<tag>, runs Postgres, applies migrations once, and serves the app on a single origin — no build step.

cp .env.example .env          # edit: pin BALANCES_TAG, set APP_URL + Google OAuth client
docker compose up             # migrations apply once, then login at http://localhost:8080

Upgrade by bumping BALANCES_TAG and running docker compose pull && docker compose up -d. The full operator walkthrough — three TLS topologies, the Google OAuth client, the upgrade contract, and database backups — is in SELF-HOSTING.md.

Licensed under AGPL-3.0 (ADR-0042).

Local development

Prerequisites: Docker (OrbStack recommended on macOS), Go 1.26.4+, Node 22+ (.nvmrc pins the version).

make setup                    # first clone only: git hooks + frontend deps + seed .env
make up                       # starts Postgres + Mailpit (docker-compose.dev.yml)
make backend-migrate-up       # applies pending migrations
make backend-run              # http://localhost:8080  (terminal 1)
make frontend-dev             # http://localhost:5173  (terminal 2)

Mailpit's web UI is at http://localhost:8025 for inspecting dev emails. The Vite dev server proxies /healthz and /api/* to the backend at :8080. make help lists every target.

Going deeper? docs/architecture.md is how the pieces fit; CONTRIBUTING.md is the workflow; CONTEXT.md is the domain glossary; the decisions behind the design live in docs/adr/; and HANDOFF.md tracks current project state (written for AI agents, but the fastest read on where things stand).

Coverage note: the frontend codecov number is scoped to src/lib/** and src/components/positionList/** (frontend/vitest.config.ts), not the whole frontend — most components and hooks aren't in the denominator yet.

About

Snapshot-based household net-worth tracker — enter your balances once a month, no transaction itemising. Self-hostable, multi-currency, broad Indonesian-instrument coverage.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages