A web application that allows users to track and manage their expenses with category-wise insights.
- Add, modify, delete, and view expenses
- Category-wise spending insights with bar charts
- Secure login and user authentication using JWT
- Search expenses by category, amount, or date
- Frontend: Vite + ReactJS, TailwindCSS
- Backend: NodeJS, ExpressJS
- Database: MongoDB
- Authentication: JSON Web Token (JWT)
- Initial design drafted in Canva: View Design
- Implemented using React + TypeScript and TailwindCSS 4
- Directory structure:
src/ ├── assets/ ├── components/ ├── screens/ ├── App.tsx └── main.tsx
- API communication is made using Axios
- Navigation between screens is done using React Router Dom
- Data visualization (Bar Charts) implemented using Chart.js and react-chartjs
- Built with Node.js, Express, and MongoDB (with Mongoose)
- Directory structure:
backend/ ├── config/ ├── controllers/ ├── middleware/ ├── models/ ├── routes/ └── index.ts
- Established database schema and relationships between models
- Implemented authentication with secure password handling
- Implemented CRUD operations for expense management
- Created endpoints for category-wise expense calculations
- Created endpoints for all the operations
- Registration:
- User provides firstname, lastname, email and password
- Password is hashed using bcryptjs with salt rounds for security
- User record created in database with hashed password
- Login:
- Email and Password are verified against the DB record
- If valid, a JWT access token and refresh token are issued
- Storage:
- JWT access token is stored in both: Secure HTTP-only cookies for security and in localstorage (for easy application state management)
- Refresh Token stored only in HTTP-only cookie
- Verification:
- Protected routes require token in
Authorization
header asBearer <token>
- User information extracted from token payload
- Protected routes require token in
- Expiration:
- Access tokens expire after 2 hours for security
- Refresh token valid for 7 days
- Automatic refresh mechanism implemented when access token expires
- Logout: JWT cookie is cleared to end the session
Users can add expenses with the following details:
- Expense name
- Amount
- Category
- Date
- Description
The process flow:
- User clicks the "+" button on the dashboard
- A modal appears with input fields, User provides details and submits
- Frontend validates all inputs and data sent to backend via
POST request
. - Backend validates data and creates expense record
- Dashboard updates to show new expense
- Update:
- Edit existing expense details
PUT request
sent to update the database record
- Delete:
- Remove expenses from the system
DELETE request
made to delete the expense from the database
- View:
- Retrieve and display all user expenses
- a
GET request
made to fetch all the expenses
An endpoint aggregates expenses by category and provides:
- Total spending per category
- Percentage breakdown of spending
- Overall total expenditure
Endpoint: GET /api/expense/insights
Example Response:
{
"categoryPercentages": [
{
"category": "Food",
"totalSpent": 200,
"percentage": 20
},
{
"category": "Travel",
"totalSpent": 800,
"percentage": 80
}
],
"totalSpent": 1000
}
1742684505341199.mp4
Collections inside the DB:

- Git
- Node.js and npm
-
Clone the repository:
git clone https://github.com/syedali237/expense-io cd expense-io
-
Create a
.env
file in the backend directory with:MONGO_URI=YOUR_DATABASE_URI JWT_SECRET=YOUR_JWT_SECRET
-
Install dependencies and start servers:
Command Location Action npm install
Frontend & Backend Install dependencies npm run dev
Frontend Start dev server at localhost:5173
npm start
Backend Start server at localhost:8000