Mizān: Local-First Personal Finance Platform
A self-hosted alternative to Monarch Money. All data stays on your machine: no telemetry, no subscriptions, no cloud database.
What I Built
Account Syncing:
- SimpleFIN Bridge integration for read-only access to thousands of financial institutions
- Coinbase Advanced Trade API integration for crypto balances and trade history
- Manual sync controls, with an opt-in
MIZAN_AUTO_SYNC_ON_STARTUPflag for automatic syncing
Local-First Storage:
- All data lives in a project-local
.mizan/directory: SQLite database, encrypted credentials, structured logs - Credentials encrypted at rest with AES-256-GCM, keyed off a machine-derived identifier, never stored in plaintext
AI-Assisted Review, Gated by Explicit Action:
- Background sync review and exploratory chat powered by Claude Sonnet 5 / Haiku 4.5
- The Cmd+K command palette and context generation run on completely local, regex/DB-based heuristics: sub-millisecond, no network calls
- Cloud LLM calls happen only for explicit chat queries or asynchronous background sync reviews, so data leaves the device only when the user actually asks something or a sync update triggers a review
Architecture
Privacy model: no data leaves the machine except for:
- SimpleFIN (transaction syncing)
- Coinbase (balance syncing) and the public
api.coinbase.com/v2/pricesspot-price endpoint (no auth) - Anthropic (only for explicit AI chat and background sync reviews)
Data layout:
.mizan/
mizan.db SQLite database
credentials.json AES-256-GCM encrypted API credentials
logs/ Structured server logs
Tech Stack
- Framework: Next.js (dev server + API on the same port)
- DB: SQLite, project-local
- AI: Claude Sonnet 5 (background review) / Haiku 4.5 (chat)
- Integrations: SimpleFIN Bridge, Coinbase Advanced Trade API
Lessons Learned
Privacy by construction:
- Splitting "local heuristics" from "cloud LLM" at the API-route level makes the privacy boundary enforceable in code, not just in a policy doc
- Encrypting credentials with a machine-derived key avoids the UX cost of a master password while still keeping secrets off disk in plaintext
Third-party APIs:
- Coinbase's OAuth for wallet-level transactions is currently unavailable for new app registrations. The Advanced Trade API covers balances and trade history in the meantime
- SimpleFIN's setup-token flow is a clean pattern for read-only bank access without ever handling bank credentials directly
Future Work
- OAuth-based Coinbase wallet transactions once client registration reopens
- Additional broker/crypto exchange integrations
- Budget forecasting on top of the existing sync data