A production-ready, full-stack personal finance tracker built with the MERN stack.
Track income & expenses Β· Visualize spending habits Β· Gain financial insights
Features β’ Tech Stack β’ Quick Start β’ API Reference β’ Deployment
| π Secure Authentication JWT tokens + bcrypt password hashing (12 rounds) |
πΈ Transaction Management Full CRUD β add, edit, delete income & expenses |
| π Interactive Dashboard Live stats for income, expenses, balance & savings rate |
π Analytics & Charts Area, bar & pie charts with monthly breakdowns via Recharts |
| π· Category Tracking Categorize expenses and view breakdown by category |
π Search, Filters & Pagination Debounced search, type/category/date filters, paginated results |
| π Dark Mode Persisted theme toggle stored in localStorage |
β‘ Blazing Fast React 18 + Vite for near-instant hot reload |
| π± Fully Responsive Mobile-first layout adapts to any screen size |
π§© Clean Architecture Separated contexts, custom hooks & modular components |
| Layer | Technology |
|---|---|
| Frontend | |
| Styling | |
| Charts | |
| State | Context API + Custom Hooks |
| Backend | |
| Database | |
| Authentication | |
| HTTP Client |
finance-tracker/
β
βββ π§ backend/ # Express REST API server
β βββ config/
β β βββ db.js # MongoDB connection setup
β βββ controllers/
β β βββ authController.js # Signup, login, getMe, updateProfile
β β βββ transactionController.js # CRUD operations for transactions
β β βββ analyticsController.js # Summary, monthly charts, categories
β βββ middleware/
β β βββ authMiddleware.js # JWT verification & route protection
β βββ models/
β β βββ User.js # User schema (name, email, password)
β β βββ Transaction.js # Transaction schema (type, amount, etc.)
β βββ routes/
β β βββ authRoutes.js # Auth endpoints
β β βββ transactionRoutes.js # Transaction endpoints
β β βββ analyticsRoutes.js # Analytics endpoints
β βββ .env.example # Environment variable template
β βββ package.json
β βββ server.js # App entry point
β
βββ βοΈ frontend/ # React SPA (Vite)
βββ src/
β βββ components/
β β βββ Auth/ # ProtectedRoute wrapper
β β βββ Dashboard/ # StatsGrid, Charts, RecentTransactions
β β βββ Layout/ # AppLayout (sidebar + header)
β β βββ Modals/ # TransactionModal, ConfirmModal
β βββ context/
β β βββ AuthContext.jsx # Auth state & methods
β β βββ TransactionContext.jsx # Transaction state & CRUD
β β βββ ThemeContext.jsx # Dark/light mode toggle
β βββ hooks/
β β βββ useAnalytics.js # Analytics data fetcher
β β βββ useDebounce.js # Debounced search input
β βββ pages/ # Login, Signup, Dashboard, Analytics, etc.
β βββ services/
β β βββ api.js # Axios instance + interceptors
β βββ utils/
β βββ helpers.js # Formatters, constants, color maps
βββ index.html
βββ vite.config.js
βββ tailwind.config.js
| Requirement | Version |
|---|---|
| Node.js | β₯ 18.x |
| npm | β₯ 9.x |
| MongoDB | β₯ 6.x (local or Atlas) |
git clone https://github.com/manishkco/FinFlow.git
cd finance-tracker# Backend
cd backend && npm install
# Frontend
cd ../frontend && npm installCreate a .env file inside backend/:
PORT=5000
MONGO_URI=mongodb://localhost:27017/finance_tracker
# For Atlas: mongodb+srv://<user>:<pass>@cluster.mongodb.net/finance_tracker
JWT_SECRET=pick_a_long_random_string_here_minimum_32_chars
JWT_EXPIRE=7d
NODE_ENV=development
β οΈ Never commit your.envfile. It's already in.gitignore.
# Terminal 1 β Start backend
cd backend
npm run dev
# β
MongoDB Connected Β· π Server running on port 5000
# Terminal 2 β Start frontend
cd frontend
npm run dev
# β‘ App running on http://localhost:5173- Navigate to http://localhost:5173
- Click "Create one" to sign up
- Start adding transactions and exploring the dashboard! π
βββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β Client ββββββΆβ Express ββββββΆβ MongoDB β
β (React) βββββββ Server βββββββ (Atlas) β
βββββββββββββββ ββββββββββββββββ ββββββββββββββββ
1. User signs up β password hashed with bcrypt (12 rounds)
2. Server generates JWT token (expires in 7 days)
3. Token stored in localStorage
4. Axios interceptor attaches "Authorization: Bearer <token>" to every request
5. authMiddleware.js verifies token on protected routes
6. Token expired/invalid β 401 β auto-redirect to /login
User Action (e.g. "Add Expense")
β
TransactionModal.jsx β form state
β
TransactionContext.addTransaction()
β
services/api.js β POST /api/transactions
β
authMiddleware β verify JWT
β
transactionController.createTransaction()
β
Transaction.create() β MongoDB
β
Response { success: true, transaction: {...} }
β
Context: prepend to state β React re-renders β UI updates β¨
| Method | Endpoint | Auth | Body / Notes |
|---|---|---|---|
| POST | /api/auth/signup |
β | { name, email, password } |
| POST | /api/auth/login |
β | { email, password } |
| GET | /api/auth/me |
β | Returns current user profile |
| PUT | /api/auth/profile |
β | { name, currency, monthlyBudget } |
| Method | Endpoint | Auth | Body / Notes |
|---|---|---|---|
| GET | /api/transactions |
β | Query: ?type=income&category=Food&search=...&page=1&limit=20&startDate=&endDate= |
| POST | /api/transactions |
β | { type, amount, category, description, date } |
| PUT | /api/transactions/:id |
β | Same as POST body |
| DELETE | /api/transactions/:id |
β | β |
| Method | Endpoint | Auth | Notes |
|---|---|---|---|
| GET | /api/analytics/summary |
β | ?month=1&year=2025 β income, expenses, savings |
| GET | /api/analytics/monthly |
β | Last 12 months of income & expenses (for charts) |
| GET | /api/analytics/categories |
β | Expense breakdown by category for the month |
Why Context API over Redux?
For a finance app of this scale, Context API provides sufficient state management with far less boilerplate. Redux adds unnecessary complexity unless the app has 10+ slices of deeply nested state.
Why Vite instead of Create React App?
Vite is 10β20Γ faster for development with near-instant hot module replacement. CRA is officially deprecated and no longer maintained.
Why separate Auth & Transaction contexts?
Separation of concerns. Auth state is required globally (header, protected routes, layout), while Transaction state is scoped to protected pages only β mounted inside
ProtectedLayout for optimal performance.
Why Recharts?
Recharts is the most popular React charting library with a fully composable API β each axis, grid, and tooltip is a separate React component, making customization straightforward.
- JWT authentication (signup, login, logout)
- Password hashing (bcrypt, 12 rounds)
- Protected routes (frontend + backend)
- Add / Edit / Delete transactions
- Income & Expense transaction types
- Category system (Food, Transport, Bills, etc.)
- Debounced search
- Filters β type, category, date range
- Pagination
- Dashboard stats (income, expenses, balance, savings rate)
- Area chart β 12-month income vs expenses
- Pie chart β expense breakdown by category
- Bar charts on Analytics page
- Monthly analytics with month selector
- Dark mode (persisted in localStorage)
- Responsive mobile layout
- Loading skeleton screens
- Toast notifications
- Profile settings (name, currency, monthly budget)
- Keyboard-accessible modals
π₯ Backend β Railway / Render
π Frontend β Vercel / Netlify
π Database β MongoDB Atlas
- Create a free cluster at cloud.mongodb.com
- Create a database user with read/write access
- Whitelist
0.0.0.0/0in Network Access (or your server IP) - Copy the connection string to your
MONGO_URIenv variable
# Recommended packages for production
npm install helmet express-rate-limit compression morgan| Package | Purpose |
|---|---|
helmet |
Security headers (XSS, clickjacking, etc.) |
express-rate-limit |
Rate limiting to prevent brute force |
compression |
Gzip compression for faster responses |
morgan |
HTTP request logging |
Tip: MongoDB indexes are already configured on
userId + dateanduserId + typefor optimal query performance.
- π Budget alerts & smart notifications
- π± React Native mobile app
- π€ Export reports (CSV / PDF)
- π€ AI-powered spending insights
- π Bank account integration (Plaid)
- π₯ Multi-user household budgeting
Manish Kumar
If you found this project useful, please give it a β star on GitHub β it means a lot!
Built with β€οΈ using the MERN Stack