Personal Finance Tracker

Next.js (App Router), TypeScript, React Query, TailwindCSS, Prisma ORM, PostgreSQL (via Supabase), Firebase Auth, Vercel

This is a personal passion project exploring full-stack development, relational database modeling, and real-time UI state management. The goal was to build a clean, responsive personal finance tool from scratch while practicing thoughtful design patterns, modular code architecture, and feature completeness.

The application includes core features like category-based budgets, savings pots with progress tracking, transaction syncing, and recurring bill setup. Each feature was designed with technical clarity and developer experience, not production usage.

The architecture supports pagination, custom form validation, optimistic UI updates, and graceful error handling. It also applies atomic design principles, separating components into atoms, molecules, and organisms for clear frontend scalability.

Recent updates included:

  • Handling pre-existing transactions when creating a new budget.

  • Fixing schema drift from updated enum fields.

  • Final code cleanup and stable syncing across budgets and transactions.

Problem Statement

Problem Statement

The project explored what a lightweight personal finance dashboard might look like if built with modern full-stack tools. Specifically, it aimed to solve the following problems:

  • How to organize expenses into category-based budgets

  • How to track savings progress through visual "pots"

  • How to maintain real-time sync between budgets and transactions

  • How to build a clean UI for adding, editing, and withdrawing from budgets and pots

  • How to securely authenticate users and persist state

  • A mobile-optimized dashboard with intuitive UI.

The app also served as a hands-on exercise in:

  • Schema modeling with Prisma

  • Declarative state management with React Query

  • Structuring scalable backend routes and services

Technical Architecture

Technical Architecture

  1. Next.js (App Router)
    Chosen for its all-in-one approach, handling routing, API logic, and SSR without needing a separate backend. It replaced the need for an Express + React combo, which felt excessive for a focused passion project.

  2. React Query
    Handled server state with features like caching, background refetching, and optimistic updates. It offered a cleaner solution than Redux (too verbose) or SWR (missing mutation support).

  3. Prisma + PostgreSQL
    Selected for type-safe schemas and excellent relational modeling, essential for linking users, budgets, transactions, and pots. It outperformed TypeORM and Sequelize in DX, syntax, and typing.

  4. Supabase
    Used as the DB host for its native PostgreSQL support, Prisma compatibility, and Row Level Security (RLS). PlanetScale was skipped due to its lack of foreign key support.

  5. Firebase Authentication
    Simple to set up, secure, and compatible with Supabase’s RLS model. Auth0 was briefly considered, but it felt like overkill for a compact project.

  6. Yup
    Form validation was powered by yup with react-hook-form, ensuring type-safe, schema-based control. Zod and Joi were considered, but yup had better integration and adoption.

  7. Vercel
    Perfect match for Next.js: fast, zero-config deployment, and instant previews. Netlify was ruled out due to its weaker support for serverless backend routes.

Core Features

Core Features

  1. Transactions

The transactions system allows users to track the amount, type (INCOME or EXPENSE), category, and recipient (if applicable) for each entry. Transactions are linked to users and budgets through Prisma relations, enabling organized and scalable financial tracking. Users can create new transactions via a dedicated modal, with real-time updates and schema-based validation ensuring smooth and accurate data entry.

  1. Budgets

Users can create, edit, and delete budgets associated with specific categories such as groceries, entertainment, or education. Each budget is automatically synced with relevant transactions, including those made prior to the budget’s creation. Budgets display a real-time progress bar to visualize spend versus remaining funds, providing an intuitive overview of financial discipline within each category.

  1. Savings Pots

Savings pots allow users to set financial goals by defining a name, target amount, current amount, and a custom color theme. Pots can be updated dynamically through modals that let users deposit or withdraw funds, while the backend schema ensures consistency and accurate tracking across the system. These visual savings goals support clear financial planning within the app.

  1. Recurring Bills

Upon signup, users receive a set of pre-defined recurring bills such as utilities, wellness, and educational services. Each bill includes attributes like name, amount, due date, payment frequency (monthly or yearly), and status (UPCOMING, DUE_SOON, or PAID). This feature simulates real-world financial obligations and encourages users to allocate budgets accordingly, supporting a more realistic budgeting experience.

  1. Reusable Modal System

A centralized modal system was developed and reused across Budgets, Transactions, and Pots. All modals were powered by react-hook-form and validated with Yup, supporting accessible, schema-safe forms with consistent styling and state management. API routes for the forms were modularized by domain to improve readability, scalability, and debugging.

Outcome & Highlights

  1. Mastered complex relational DB design across Budgets, Pots, Transactions.

  2. UX-first dev: Clean user flows across cards, modals, dashboards.

  3. Owned end-to-end dev: Feature planning, schema, UI, API, and deployment.

  4. Scalable architecture using consistent services, types, and hooks.