Pocket Cash
Offline-first desktop app that turns messy bank CSV exports into categorised spending, net-worth trends and tax-time reports. No account, no cloud, no telemetry.

Overview
Pocket Cash is an offline-first personal finance app for the desktop. It turns bank CSV exports into an organised view of spending, net worth and financial-year reporting, and it runs entirely on your own machine. There is no sign-in, no server, and no analytics. The database lives in the app's own folder and nothing leaves the device.
Key Features
- Bank-agnostic CSV import: Map a statement's columns once, and that mapping becomes a reusable importer for every future export from that bank
- Safe re-imports: Each account fingerprints its rows, so re-importing the same file skips duplicates instead of double-counting
- Categorisation: Organise transactions into categories and tags, with spending broken down per category and per month
- Net worth across accounts: Balances and trends aggregated across every account you track
- Tax-time reporting: Financial-year summaries and a tax report that exports to CSV
- Optional AI: Auto-categorising, insights and a deduction scan, off by default, and able to run fully offline against a local model
Technical Stack
- Shell: Electron, packaged as a downloadable desktop release
- UI: Next.js, React, Tailwind CSS
- Database: PGlite, Postgres compiled to WASM, running in-process
- Data access: Drizzle ORM
- Monorepo: Turborepo
Architecture
Pocket Cash inverts the usual finance-app architecture: instead of a hosted backend holding the data, the entire stack ships to the user's machine.
- Local database: PGlite gives a real Postgres engine with no server to run and no connection to configure
- Typed data layer: Drizzle ORM over that local database
- Desktop shell: Electron wraps the Next.js UI and owns the app's data directory
- Import pipeline: Column mapping, row fingerprinting and deduplication sit between a raw CSV and the ledger
Challenges & Solutions
- Privacy without a backend: Chose a local-first design so there is no account system, no hosting and no telemetry to secure in the first place; the privacy guarantee comes from the architecture rather than from policy
- Every bank exports differently: Solved with a reusable per-account column mapping rather than trying to detect formats automatically
- Re-importing overlapping statements: Row-level fingerprinting makes imports idempotent, so an overlapping date range cannot double-count
- Postgres with no server: PGlite provides real Postgres semantics in-process, avoiding both a bundled database server and the limitations of SQLite for reporting queries
Impact & Results
- Privacy by construction: Financial data never leaves the device, because there is nowhere for it to go
- Reusable importers: The one-time column mapping removes the repetitive part of tracking spending
- Tax preparation: Financial-year and deduction reporting exports directly to CSV
- Distribution: Shipped as a versioned desktop release with CI, under a PolyForm Noncommercial licence
Interested in working together?
I'm Thomas Iwainski, a Senior Software Engineer based in Sydney, Australia. Send me a note and I'll get back to you.