A full-stack MERN expense tracker with JWT cookie authentication, demo sessions, transaction filtering, and rich analytics.
Live demo: expense-management-system-bice.vercel.app
Design (Google Stitch): View Stitch Project →
| Layer | Technology |
|---|---|
| Frontend | React 18, Ant Design v5, Recharts, Axios, React Router v6, Day.js |
| Backend | Node.js, Express, express-rate-limit, Morgan |
| Database | MongoDB + Mongoose |
| Auth | JWT (httpOnly cookie) + bcryptjs |
| Deployment | Vercel (frontend), Render (backend API) |
- Register & login with secure JWT httpOnly cookie auth
- Demo mode — try the app instantly with pre-seeded transactions, no account needed
- Add, edit, delete transactions (amount, type, category, date, description)
- Filter by frequency: last 7 days / 30 days / 1 year / custom date range
- Filter by transaction type: All / Income / Expense
- KPI summary cards: Total Balance, Total Income, Total Expense
- Analytics view with three interactive Recharts visualisations:
- Area chart — income vs expense over time
- Donut chart — income vs expense split
- Horizontal bar chart — category-level breakdown
- Password update from the profile dropdown
- Demo data reset ("Clear Demo Data") for demo sessions
- Rate-limiting on auth endpoints (express-rate-limit)
- TTL-based automatic cleanup of demo accounts via MongoDB TTL index
- Fully responsive — desktop, tablet & mobile
Expense-Management-System/
├── client/ # React frontend (Create React App)
│ ├── public/
│ └── src/
│ ├── components/
│ │ ├── Analytics.js # Recharts area / donut / bar charts
│ │ ├── ErrorBoundary.js # React error boundary wrapper
│ │ ├── FilterBar.js # Frequency, type filter + view toggle
│ │ ├── Spinner.js # Loading spinner
│ │ ├── transactionModal.js # Add / edit transaction modal
│ │ └── Layout/
│ │ ├── Header.js # App header with avatar dropdown
│ │ ├── Footer.js
│ │ └── Layout.js
│ ├── pages/
│ │ ├── HomePage.js # Main dashboard (KPI cards + table/analytics)
│ │ ├── Login.js # Login page with demo login button
│ │ └── Register.js
│ └── utils/
│ └── categories.js # Shared transaction category list
├── server/ # Express backend
│ ├── controllers/
│ │ ├── transactionCtrl.js # CRUD + delete-all-transactions
│ │ └── userController.js # Register, login, logout, demo, password update
│ ├── middleware/
│ │ └── authMiddleware.js # JWT cookie verification
│ ├── models/
│ │ ├── transactionModel.js
│ │ └── userModel.js # TTL index on expiresAt for demo cleanup
│ ├── routes/
│ │ ├── transactionRoutes.js
│ │ └── userRoute.js # Rate-limited auth routes
│ ├── scripts/
│ │ └── seedTransactions.js
│ └── utils/
│ └── demoData.js # Pre-seeded demo transaction generator
├── docs/
│ └── screenshots/
│ ├── v1/ # Original UI screenshots
│ └── v2/ # Redesigned UI screenshots
└── render.yaml # Render static deployment config
- Node.js >= 16
- MongoDB (local or Atlas)
git clone https://github.com/RaviPandey2002/Expense-Management-System.git
cd Expense-Management-Systemcd server
cp .env.example .env # fill in your values
npm install
npm run devServer .env variables:
PORT=8000
MONGO_URL=your_mongodb_connection_string
JWT_SECRET=your_jwt_secret
CLIENT_URLS=http://localhost:3000
NODE_ENV=developmentNote: The server defaults to port 8000. Keep
PORTin.envandREACT_APP_API_BASE_URLin the client.env.developmentin sync.
cd client
npm install
npm startClient .env.development variable:
REACT_APP_API_BASE_URL=http://localhost:8000/api/v1| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/v1/users/register |
✗ | Create a new account |
POST |
/api/v1/users/login |
✗ | Login & receive JWT cookie |
POST |
/api/v1/users/logout |
✗ | Clear JWT cookie |
POST |
/api/v1/users/demo-login |
✗ | Start a 2-hour demo session |
PUT |
/api/v1/users/update-password |
✓ | Change account password |
POST |
/api/v1/transactions/get-transactions |
✓ | Fetch filtered transactions |
POST |
/api/v1/transactions/add-transaction |
✓ | Add a transaction |
POST |
/api/v1/transactions/edit-transaction |
✓ | Edit a transaction |
POST |
/api/v1/transactions/delete-transaction |
✓ | Delete a transaction |
POST |
/api/v1/transactions/delete-all-transactions |
✓ Demo | Clear all demo transactions |
GET |
/health |
✗ | Backend health check |
This project was visually redesigned using Google Stitch, an AI-assisted UI design tool.
The original UI (v1) screenshots are preserved in docs/screenshots/v1/ and the new v2 design in docs/screenshots/v2/ for clear before/after comparison.
| Version | Description | Link |
|---|---|---|
| v1 | Original UI — functional but basic | See docs/screenshots/v1/ |
| v2 | Redesigned UI — Google Stitch assisted | Stitch Project → |
Why document this? Tracking design iterations shows a professional development workflow — from working software → clean code → polished UI.
| Login Page | Dashboard |
![]() |
![]() |
| Add Transaction | Analytics |
![]() |
![]() |
| Login Page | Register Page |
![]() |
![]() |
| Normal User Dashboard | Demo User Dashboard |
![]() |
![]() |
| Transaction Modal | Analytics Page |
![]() |
![]() |
| Login | Register | Dashboard |
![]() |
![]() |
![]() |
| Transaction Modal | Analytics 1 | Analytics 2 |
![]() |
![]() |
![]() |
- Fork the project
- Create your feature branch:
git checkout -b feature/your-feature - Commit your changes:
git commit -m 'feat: add your feature' - Push to the branch:
git push origin feature/your-feature - Open a Pull Request
Distributed under the MIT License.
Ravi Pandey















