Expense Tracker
A web interface that records expenses and summarises them. Your first project with real UI state and accessibility requirements.
Technologies
The brief
What the finished thing needs to do.
- Add an expense with a description, amount, category and date
- List expenses, most recent first
- Show the total, and a breakdown by category
- Filter by category and by date range
- Delete an expense
- Work properly on a phone screen
- Be fully operable with a keyboard
How to structure it
Components split by responsibility: a form for entry, a list, a row, and a summary panel. The list owns the collection; the row renders one item and knows nothing about the others.
State lives at the lowest level that can serve everyone who needs it. The expense collection belongs in the page component since the form, list and summary all depend on it.
Derive the totals from the expense list rather than storing them separately. Two sources of truth for the same number will eventually disagree.
Why these technologies
- React with TypeScript
- Typed props catch shape mismatches, which is most of what goes wrong in forms.
- Local state, no backend initially
- Keeps the focus on UI and state modelling. Persistence is a later stage.
- Semantic HTML form elements
- Correct elements supply keyboard support and screen reader labelling without extra work.
Build it in this order
Each stage produces something that works. That matters — a project that only runs at the very end is a project people abandon.
Display a fixed list
Hard-code three expenses and render them. Get the layout right first.
Add the summary
Calculate the total from the list. Derive it, do not store it.
Build the form
Controlled inputs with proper labels. Validate before adding.
Wire the form to the list
Adding an expense should update both the list and the summary, because both read the same state.
Add the category breakdown
Group the expenses by category and show totals per group.
Add filtering
Filter derived from state rather than mutating the stored list.
Add deletion
Use a stable id as the key, never the array index.
Make it responsive and accessible
Test with keyboard only, and at a narrow viewport.
Done means
How to know it is finished
Check each of these before moving on. If one fails, the project is not done yet — and that is useful information rather than a setback.
- Adding an expense immediately updates the list, the total and the category breakdown
- Filters narrow the display without losing the underlying data
- Every interactive element is reachable and operable by keyboard
- Form fields have associated labels, not just placeholder text
- The layout is usable at a phone width
If you want to go further
Extensions worth attempting
Only once the core build meets every criterion above.
- Persist to localStorage so data survives a refresh
- Add a chart showing spending by month
- Add a budget per category and indicate when one is exceeded
- Replace local state with a real API and handle loading and error states
Other projects at this level
Console Calculator
Your first program that does something useful. Reads input, validates it, calculates, and handles the cases that go wrong.
To-Do List Application
Manage a list that changes: add, complete, remove and display items. Your first program with real state.
Contact Manager
A mobile-shaped application for storing contacts, with search and offline-tolerant local storage.
Have a project worth talking through?
Tell us what you're building or what's slowing your current system down. We'll give you a direct read on scope and approach.