The Problem
Personal finance tools fall into two camps: spreadsheets that are clunky and hard to maintain, or proprietary apps that lock your data behind opaque algorithms and subscriptions. Neither gives you full control over both the data and the analytical layer.
This project is a self-hosted, full-stack budgeting dashboard – The goal was to build a full production-ready app, while having full ownership of the data.
Technical Approach
The system is split into a FastAPI backend and a React + Vite frontend, connected through a RESTful API with Pydantic-validated request/response schemas throughout. As a database I decided to use Supabase for its free tier and easy-to-use authentication.
Backend Architecture
The backend is structured around dedicated routers, each handling a bounded domain.
Key backend decisions:
- Supabase PostgreSQL – hosted database with row-level security, removing the need to manage infrastructure while keeping full SQL access.
- Authentication – Supabase Auth handles secure login, with GitHub and Google OAuth for easier registration.
- Rate limiting – SlowAPI middleware to prevent abuse on public endpoints.
- Polars – used for analytics aggregation where pandas would be unnecessarily slow.
Frontend
- React + Vite – component-driven UI with TypeScript throughout.
- Recharts – interactive charts for category breakdowns, monthly trends, and daily spending patterns.
- TailwindCSS – utility-first styling for rapid iteration.
Stack Overview
| Layer | Technology |
|---|---|
| Frontend | React, Vite, TypeScript, TailwindCSS |
| Visualisation | Recharts |
| Backend | FastAPI, Pydantic, PyJWT, Polars |
| Rate Limiting | SlowAPI |
| Database | Supabase (PostgreSQL) |
| Auth | Supabase, GitHub OAuth, Google OAuth |
| CI/CD | GitHub Actions → Render |
CI/CD Pipeline
The project runs a full CI/CD workflow:
- CI (GitHub Actions) – on every PR to
main, the pipeline runs backend type-checking, tests and frontend lint, type-check, build. - CD (Render) – deployments trigger only after CI passes, ensuring the live services always update from verified builds.
Development Process
The frontend UI was vibe coded with Lovable to move quickly through layout and interaction ideas. From there, I iteratively redesigned, extended, and connected it to a fully custom backend API, including authentication, analytics endpoints, state management, and CSV export functionality.
The backend, database schema, authentication setup, Supabase policies, and deployment pipeline were built manually from scratch.
Results & Impact
| Feature | Status |
|---|---|
| Transaction CRUD | ✓ |
| Category management | ✓ |
| Multi-account support | ✓ |
| Monthly analytics & KPIs | ✓ |
| Yearly analytics | ✓ |
| Daily spending charts | ✓ |
| Budget tracking | ✓ |
| Savings fund management | ✓ |
| CSV export | ✓ |
| CSV import | ✗ |
| GitHub OAuth | ✓ |
| Google OAuth | ✓ |
| Rate limiting | ✓ |
| CI/CD pipeline | ✓ |
The application has been in daily personal use by me and my family members – a real product solving a real problem, not a tutorial exercise.
Code & Artifacts
What I'd Do Differently
I would focus on CI/CD pipeline from the start, utilizing mypy or pytests on backend and lint on the frontend. This way I would create clean code from the start, without the need to rewrite some of the parts.