Skip to main content
ANVISoftware Solutions

Expense Tracker

Beginner10-15 hours

A web interface that records expenses and summarises them. Your first project with real UI state and accessibility requirements.

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.

  1. Display a fixed list

    Hard-code three expenses and render them. Get the layout right first.

  2. Add the summary

    Calculate the total from the list. Derive it, do not store it.

  3. Build the form

    Controlled inputs with proper labels. Validate before adding.

  4. Wire the form to the list

    Adding an expense should update both the list and the summary, because both read the same state.

  5. Add the category breakdown

    Group the expenses by category and show totals per group.

  6. Add filtering

    Filter derived from state rather than mutating the stored list.

  7. Add deletion

    Use a stable id as the key, never the array index.

  8. 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

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.