BudgetMate is a MERN (MongoDB, Express, React, Node) application that I’m using to manage personal expenses, with authentication and a few visual reports to understand spending patterns.
The project is split into:
- Backend – Node/Express REST API on top of MongoDB (via Mongoose)
- Frontend – React + React Router + Material‑UI
- Reports – Charts powered by
victoryto visualize expenses
- User accounts
- Register, log in, log out
- Edit and delete your own profile
- Authentication & security
- JWT‑based auth (
express-jwt,jsonwebtoken) - Protected backend endpoints and React
PrivateRouteon the client - Extra middleware like
helmet,compression, andcors
- JWT‑based auth (
- Expense management
- Add new expenses
- Browse all saved expenses
- Quick overview on the home page for signed‑in users
- Reports
- Monthly scatter chart
- Yearly bar chart
- Category‑wise pie chart
- Available under
/expenses/reports
- Server‑side rendering
- Server renders the initial React markup
- Material‑UI styles are generated on the server and attached to the HTML
Main folders and what they contain:
server/– Express app, routes, controllers, and data modelsserver/server.js– Connects to MongoDB and starts the HTTP serverserver/express.js– Express configuration, middleware, SSR setup, and route wiringserver/models/– Mongoose models (user.model.js,expense.model.js)server/controllers/– Logic for auth, user, and expense APIsserver/routes/– Route definitions for the REST API
client/– The React frontendclient/main.js– Bootstraps the client bundleclient/App.js– Root React component with routing and themingclient/MainRouter.js– Main route configuration, includingPrivateRouteclient/core/– Home page and navigationclient/auth/– Sign in page, auth helpers, and private route logicclient/user/– User list, profile, edit profile, delete userclient/expense/– Create, view, and delete expenses, plus overviewclient/report/– Reporting views:CategoryPie,MonthlyScatter,YearlyBar,Reportsclient/theme.js– Shared Material‑UI theme
config/config.js– Central configuration (port, DB URI, JWT secret)template.js– Base HTML markup for server‑side rendering- Webpack configs – Build pipeline for both client and server bundles
- Node.js: v13+ (any modern LTS should be fine)
- npm or yarn
- MongoDB: running either locally or in the cloud (e.g. Atlas)
- Install dependencies
npm installThis pulls in everything needed for both the backend and frontend.
- Configure environment (recommended)
Create a .env file or set environment variables in your shell to override the defaults in config/config.js:
NODE_ENV–development(default) orproductionPORT– HTTP port (default:3000)JWT_SECRET– Secret string used to sign JWTs (default:"YOUR_secret_key", which you should change)MONGODB_URI– Full MongoDB connection string (takes precedence)MONGO_HOST/MONGO_PORT– Host and port for MongoDB (defaults:localhost:27017)
If you don’t set MONGODB_URI, the app falls back to something like:
mongodb://<MONGO_HOST or localhost>:<MONGO_PORT or 27017>/budgetmate
Make sure MongoDB is running and reachable from the server.
Runs the Express server together with webpack dev middleware and hot reloading:
npm run developmentThen open http://localhost:3000 in your browser.
In development,
devBundle.compile(app)is enabled inserver/express.jsto plug webpack into Express.
/– Home page- When signed out: landing page with hero image and links to sign up / sign in
- When signed in: shows
ExpenseOverview
/signup– User registration/signin– User login/users– List of registered users/user/:userId– User profile/user/edit/:userId– Edit profile (protected)/expenses/new– Add a new expense (protected)/expenses/all– View all expenses (protected)/expenses/reports– View charts/reports (protected)
Routes marked as protected require authentication and are wrapped with PrivateRoute.
This is a simplified overview; the actual endpoints live in server/routes/ and server/controllers/.
- Auth
POST /auth/signin– Sign in, returns JWTGET /auth/signout– Sign out (client mostly handles local state)
- Users
POST /api/users– Create userGET /api/users– List usersGET /api/users/:userId– Get a single userPUT /api/users/:userId– Update userDELETE /api/users/:userId– Delete user
- Expenses
- Endpoints to create, read, and delete expenses; some are scoped to the current user and require a valid JWT.
Protected routes use express-jwt middleware and return 401 on invalid or expired tokens.
-
Frontend
- React (
react,react-dom) - Routing via
react-router/react-router-dom - UI components and theming from
@material-ui/core,@material-ui/icons,@material-ui/styles,@material-ui/pickers - Data visualization with
victory - Hot reloading with
react-hot-loader(development)
- React (
-
Backend
- Express (
express) - MongoDB with Mongoose (
mongoose) - Authentication:
jsonwebtoken,express-jwt - Middleware:
body-parser,cookie-parser,compression,cors,helmet
- Express (
-
Build & Tooling
- Webpack (client + server bundles)
- Babel with
@babel/preset-envand@babel/preset-react - Nodemon for development server reloads
- Server‑side rendering (SSR)
- Done in
server/express.jswithReactDOMServer.renderToString - Uses
StaticRouterand a shared Material‑UIThemeProvider - Injects the collected CSS into the HTML template from
template.js
- Done in
- Client hydration
client/App.jsremoves the server‑side JSS styles after the first render to avoid duplicate styles
- Auth helper
client/auth/auth-helper.jsstores JWTs in localStorage and attaches auth headers to API requests
- Tweak the theme in
client/theme.jsto adjust colors, typography, and overall styling. - Extend the expense model and controllers if you want extra fields like tags, notes, or recurring flags.
- Add more visualizations under
client/report/(different time ranges, comparisons, exports, etc.).