Skip to content

Transaction Tracker: a MERN finance tracker app with live dashboards and reports

A case study in building a TypeScript MERN app for recording and categorising money in and out, with charts that follow every edit, custom reports and admin account management.

Transaction Tracker dashboard with summary cards for income and expenses, a spending chart by category and a list of recent transactions

Transaction Tracker is a MERN finance tracker app I built in TypeScript for recording, editing and categorising personal transactions. A dashboard turns those records into charts and summaries that update as entries change, custom reports cover a chosen period, and an admin panel manages accounts. It runs on React, Node.js, Express.js and MongoDB, with JWT authentication and bcrypt password hashing.

The problem

Keeping track of money usually starts in a spreadsheet or a notes app, and it usually stops there too. Entries get typed in inconsistently, categories multiply, and the moment you want to know where the money went last month you are building formulas instead of reading an answer.

The other common option, a banking app, only knows about one account and shows a feed of payments without letting you correct, regroup or annotate them. I wanted a tracker where entering a transaction took seconds, fixing a wrong category was a single edit, and the summary on the dashboard reflected that change straight away.

My role

I built Transaction Tracker end to end in TypeScript: the React interface with Tailwind CSS and shadcn/ui, the Node.js and Express.js API, the MongoDB data model for users and transactions, JWT authentication with bcrypt, the dashboard charts, the report generator, and the admin panel for managing accounts. The code is kept on GitHub.

Architecture and tech stack

Transactions as the only source of truth

The app stores individual transactions, each with an amount, a type, a category and a date, and nothing else about money. Totals, category breakdowns and reports are all computed from those records rather than kept as running balances. That costs a little computation, but it means correcting one old entry can never leave a stored total out of step.

Express.js routes shaped around the dashboard

The Express API exposes the usual create, edit and delete routes for transactions, plus summary routes that return the figures the dashboard and reports need already aggregated. The browser receives a handful of numbers for a chart instead of every transaction in the account, which keeps the dashboard quick as a history grows. I took a similar route-first approach to a different domain in the Elentra Car API.

shadcn/ui and Tailwind CSS for dense forms

Most of the time in a finance app is spent in forms and tables. shadcn/ui components give accessible inputs, selects and dialogs that I could restyle with Tailwind CSS, so adding or editing a transaction happens in a dialog over the list without losing your place.

Key features

  • Transaction management: add, edit and categorise income and expenses, with the list updating straight away.
  • An interactive dashboard with charts and summaries of where money comes from and goes.
  • Custom reports for a chosen period, built from the same records as the dashboard.
  • An admin panel for overseeing and managing user accounts.
  • Profile management for personal details and settings.
  • JWT authentication with bcrypt-hashed passwords.
  • A responsive interface built with React, Tailwind CSS and shadcn/ui.

Challenges and how I solved them

Charts that follow every edit

Problem
When a user changes a transaction's amount or moves it to another category, the list, the summary cards and the charts all have to change together. If only the edited row updates, the dashboard quietly shows numbers that are no longer true.
Solution
After any create, edit or delete, the dashboard summaries are fetched again from the API, which recomputes them from the stored transactions. The list, the cards and the charts are all drawn from that fresh response, so they agree with each other and with the database.

Categories that stay useful

Problem
Free-text categories fall apart within weeks: "Food", "food" and "Groceries" end up as three slices of the same pie chart, and the breakdown stops meaning anything.
Solution
Transactions are categorised by picking from a list rather than typing a label each time, which keeps the grouping consistent and lets the dashboard and reports group spending reliably.

Admin powers in a personal finance app

Problem
Someone has to be able to manage accounts, but a person's transactions are private. The admin role needed real authority over users without turning the admin panel into a window onto everyone's spending.
Solution
The admin panel is built around account management, and the API checks the role carried in the JWT before any admin route runs. The pattern is close to the role checks in MERN Mail, applied here to protecting financial records instead of outreach logs.

Results

Transaction Tracker gives a single person a clear, editable record of their money: entries go in quickly, mistakes are cheap to fix, and the dashboard and reports always reflect the current data. For a version of the same MERN stack with three roles and a shared workspace rather than private records, see the Team Management System.

What's next

Possible additions include budgets per category and importing transactions from a bank statement file, though neither is a committed plan yet.

Need a full-stack developer for a product like this?

I work remotely with teams in the US, Canada, the UK, Europe and the Gulf, and with clients across Pakistan. Based in Pakistan (PKT, UTC+5), available for freelance and full-time roles.