Spendio
2026
A personal finance tracker for accounts, transactions, transfers, budgets, recurring bills, and savings goals.
Links
In a nutshell
Spendio is an app for managing personal finances. I can add bank accounts, e-wallets, and cash; record income and expenses; move money between accounts; set budgets; schedule repeating bills; and save toward a goal. The dashboard shows my balance, my income and expenses, and where my money went this month.
Why I built this
I wanted one place to see where my money went without updating a spreadsheet. It also gave me a reason to build a real backend: an API, a database schema, and auth that I control from end to end.
What it solves
Spreadsheets get messy when money moves between accounts and bills repeat. Spendio keeps everything connected, so a transaction updates the right balance and the monthly summary at the same time.
How it's built
- The app
- Next.js 16 with the App Router, React 19, and Tailwind CSS 4. The dashboard, transactions, accounts, categories, budgets, recurring, and savings pages are all built.
- Backend
- An Express 5 API with PostgreSQL 17 and Drizzle ORM. Types and Zod schemas live in a shared workspace package, so the web app and the API validate requests against the same contract.
- Balances
- Money is stored as numeric(16,2) and handled as strings in TypeScript, and balance updates run in SQL inside one database transaction. A transfer or expense cannot leave an account balance drifting or add floating-point rounding.
- Login
- Better Auth handles email/password with verification and password reset, plus optional Google sign-in. Every /api/v1 route requires an authenticated session.
- Testing & deploy
- Vitest covers money handling, date helpers, email rendering, and API responses. In production the API runs as a systemd service behind nginx on AWS EC2, with PostgreSQL in Docker.
Result
Spendio is live here. The whole stack is mine: the Next.js app, the Express API, the Postgres schema, and the deployment. Building it taught me a lot about auth, database transactions, and keeping money numbers correct.