Nexfi
The headline number is always what is still available.
271
requirements
65
invariants
10
state machines
98.9%
line coverage
Why it exists
Monarch, Mobills, YOLO — the serious personal-finance tools all bill you every month for the privilege of looking at your own money. That has the order backwards. Financial freedom can start with the ordinary kind: run Nexfi on a machine in your own house, or pay for the convenience of having it ready and running. Both doors are open, and the self-hosted one is not the crippled version.
The other half is scope. Expenses, credit cards, investments, savings pots, net worth and the metrics over all of it, in one place — because a financial life split across four apps is not organised, it is only filed.
The problem
Personal finance tools shout about what you spent, gamify saving into streaks and badges, silently convert currencies, and hold your history hostage the moment you stop paying.
Nexfi inverts each of those as a binding principle rather than a preference: the number on screen is what remains, there are no streaks, no conversion happens without being asked for, and an expired plan degrades to read-only instead of locking you out.
Architecture
The deciding constraint was not language preference — it was how many moving parts a self-hoster has to run. The target was two containers, and everything else followed from it.
Django and DRF serve a Vite-built React SPA as static files, so there is no Node process in production. One codebase covers three topologies: a single container on SQLite small enough for a Raspberry Pi, the standard two-container self-host with PostgreSQL, and a cloud deployment where the additions are adapter swaps rather than different code.
The domain layer imports nothing from Django.
Decisions worth explaining
- 01
Money is stored as BIGINT minor units with a CHAR(3) currency, not DECIMAL. SQLite's NUMERIC affinity silently degrades to float, which would have violated a core invariant invisibly — the failure would have been rounding errors nobody could trace.
- 02
PostgreSQL row-level security was demoted from primary tenancy enforcement to optional hardening. It works, but it is PostgreSQL-only, and that contradicts a database-agnostic promise. CI runs the full suite against PostgreSQL, MySQL and SQLite.
- 03
The tenancy anchor is unconditional even though household features are optional. Retrofitting tenancy is one of the most expensive migrations in software; retrofitting an invitation flow is a feature.
- 04
Licensed AGPL-3.0 with a CLA, because section 13 is what makes running a modified fork as a service carry an obligation. The cloud sells hosting, market data and EU compliance — things with marginal cost — never features.
- 05
Open core was considered and explicitly rejected. The feature-flag architecture makes it technically trivial, which is precisely the temptation.
Stack
Status
Substantially built and not released: the specification set is complete, the domain and money core are covered well past their floors, and the first three milestones are closed. There is no public version to try yet.