A simple, secure expense tracker web app built with a React frontend and a Node/Express + MongoDB backend.
Includes: auth (signup/login), protected routes, expense & income management, file uploads (receipts), and a clean componentized React UI.
- Demo / Screenshots
- Features
- Tech stack
- Repository structure
- Requirements
- Installation
- Backend
- Frontend
- Environment variables
- Start / Development
- API overview](#api-overview)
- Authentication flow
- Future improvements
- Contributing
- User registration & login (JWT-based)
- Protected API endpoints (authenticated user only)
- Create / Read / Update / Delete expenses & income
- Categorization, amount, date, description for each entry
- File upload support (receipt images)
- React componentized UI (Cards, Charts, Layouts, Modal, Alerts)
- MongoDB as the datastore
- Error handling and validation on backend
- Frontend: React Vite, React Router, Context/hooks
- Backend: Node.js, Express
- Database: MongoDB Atlas
- Auth: JWT (
jsonwebtoken) - File uploads:
multer - Dev tools:
nodemon
expense-tracker/
├─ backend/
│ ├─ middleware/
│ ├─ models/
│ ├─ routes/
│ ├─ uploads/
│ ├─ .env
│ ├─ package.json
│ └─ server.js
├─ frontend/
│ ├─ public/
│ ├─ src/
│ │ ├─ assets/
│ │ ├─ components/
│ │ │ ├─ Cards/
│ │ │ ├─ Charts/
│ │ │ ├─ Dashboard/
│ │ │ ├─ Expense/
│ │ │ ├─ Income/
│ │ │ ├─ input/
│ │ │ └─ layout/
│ │ │ ├─ DeleteAlert.jsx
│ │ │ ├─ EmojiPickerPopup.jsx
│ │ │ └─ Modal.jsx
│ │ ├─ context/
│ │ ├─ hooks/
│ │ ├─ pages/
│ │ ├─ utils/
│ │ ├─ App.css
│ │ |__ App.jsx
| | ├─ index.css
| | ├─ main.css
│ │ └─ index.html
│ ├─ package.json
└─ README.md
- Node.js (LTS recommended)
- npm
- MongoDB Atlas
- Open terminal and go to
backend/ - Install dependencies:
cd backend
npm install- Create
.envinbackend/(see Environment variables) - Run server:
# development with nodemon (if configured)
npm run dev
Typical backend scripts in package.json:
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
}- Open another terminal and go to
frontend/ - Install dependencies:
cd frontend
npm install- Create any required frontend
.env(if needed) - Run:
npm run devExample .env for backend (replace placeholder values):
PORT=8000
MONGO_URI=mongodb+srv://<user>:<password>@cluster0.mongodb.net/expense-tracker?retryWrites=true&w=majority
JWT_SECRET=your_super_secret_jwt_key
Security note: Never commit .env to git. Add to .gitignore.
Run backend and frontend concurrently (optional):
# from project root, you can use concurrently in package.json to start both
npm run dev:alldev:all example in root package.json could be:
"scripts": {
"dev:all": "concurrently \"cd backend && npm run dev\" \"cd frontend && npm start\""
}All protected endpoints require header
Authorization: Bearer <token>
-
POST /api/auth/register— register a new user body:{ "name": "...", "email": "...", "password": "..." }response:{ user, token } -
POST /api/auth/login— login body:{ "email": "...", "password": "..." }response:{ user, token }
GET /api/expenses— list user’s expensesPOST /api/expenses— create expense body:{ "title", "amount", "category", "date", "notes" }GET /api/expenses/:id— get single expensePUT /api/expenses/:id— update expenseDELETE /api/expenses/:id— delete expense
GET /api/income— list user’s income recordsPOST /api/income— create income recordPUT /api/income/:id— updateDELETE /api/income/:id— delete
-
POST /api/uploads— upload receipt image (multipart/form-data, use multer)- returns stored file URL or path
- User registers — server creates user record and returns JWT token.
- Frontend stores token (recommended:
httpOnlycookie or localStorage — note XSS/CSRF tradeoffs). - For requests to protected routes, frontend sends
Authorization: Bearer <token>. - Server middleware verifies token, sets
req.user, and forwards request.
Register:
curl -X POST http://localhost:5000/api/auth/register \
-H "Content-Type: application/json" \
-d '{"name":"John Doe","email":"john@example.com","password":"password123"}'Create expense (authenticated):
curl -X POST http://localhost:5000/api/expenses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <TOKEN>" \
-d '{"title":"Coffee","amount":3.5,"category":"Food","date":"2025-09-21"}'- Keep
JWT_SECRETsafe, rotate periodically. - Prefer httpOnly cookies + CSRF protections for auth if you can — otherwise carefully protect against XSS when using localStorage.
- Validate and sanitize input on the server.
- Restrict upload file types and sizes; store uploads outside web root or use cloud storage.
- Recurring expenses
- CSV import/export
- Charts & analytics by category & period
- Mobile-responsive improvements
- Role-based access (multi-user/teams)
- Monthly budget and notifications
- Unit & integration tests
- Fork the repo
- Create a feature branch:
git checkout -b feat/your-feature - Commit changes:
git commit -m "feat: add ..." - Push and open a PR
Add clear issues and describe the feature or bug, include screenshots where helpful.
MONGO_URIconnection errors → check credentials and IP whitelist (Atlas).CORSissues → configurecors()in Express and ensure frontend origin is allowed.File upload413 errors → check multer limits and server body parser limits.
Created by — Vishvak, LinkedIn : https://www.linkedin.com/in/vishvak-r/