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