A full-stack Notes application built with the MERN stack (MongoDB, Express, React, Node.js) with modern UI and production-ready features like rate limiting, notifications, and deployment support.
- βοΈ Create, update, and delete notes
- π View all notes with clean UI
- π Rate limiting using Upstash Redis
- π Toast notifications with react-hot-toast
- π¨ Modern UI with Tailwind CSS + DaisyUI
- π Light/Dark theme support
- β‘ Fast API calls using Axios
- βοΈ Deployment ready (Render)
- React.js
- Tailwind CSS
- DaisyUI
- Axios
- React Hot Toast
- Lucide React (icons)
- Node.js
- Express.js
- MongoDB Atlas
- Mongoose
- Upstash Redis (Rate Limiting)
βββ src/
β βββ components/
β βββ pages/
β βββ lib/
β βββ App.jsx
backend/
βββ src/
β βββ controllers/
β βββ routes/
β βββ models/
β βββ middleware/
β βββ config/
Create a .env file in your backend:
MONGO_URI=your_mongodb_connection_string
PORT=5001
UPSTASH_REDIS_REST_URL=your_upstash_url
UPSTASH_REDIS_REST_TOKEN=your_upstash_token git clone https://github.com/danishdynamic/FullStack-Mern.git
cd notes-appcd backend
npm installcd frontend
npm installcd backend
npm run devcd frontend
npm run dev | Method | Endpoint | Description |
|---|---|---|
| GET | /api/notes | Get all notes |
| GET | /api/notes/:id | Get note by ID |
| POST | /api/notes | Create note |
| PUT | /api/notes/:id | Update note |
| DELETE | /api/notes/:id | Delete note |
Rate limiting is implemented using Upstash Redis to prevent abuse.
- Applied to write operations (POST, PUT, DELETE)
- Uses IP-based limiting
- Responsive layout
- Clean card-based design
- Theme switching (light/dark)
This app is deployment-ready:
- Frontend β Render / Vercel
- Backend β Render
- Database β MongoDB Atlas
- Rate limiting β Upstash Redis
- For production we can also use Unified Monorepo such as moving both frontend and backend into a single repository with shared configuration.(optional as we have to update cors and server.js and add a file i.e package.json).
- In package.json and server.js we can add the following scripts to run both frontend and backend together in production.
- package.json
"scripts": {
"start": "node server.js",
"build": "npm install && cd frontend && npm install && npm run build",
"test": "vitest run"
}
-server.js
// SERVE FRONTEND and import path module
if (process.env.NODE_ENV === 'production') {
// Point to the frontend build folder
app.use(express.static(path.join(__dirname, './frontend/dist')));
// Handle SPA routing: send all non-API requests to index.html
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'frontend', 'dist', 'index.html'));
});
}- If you want to deploy both frontend and backend separately i.e Decoupled Architecture. We can deploy backend (render)first and then update the frontend (vercel )API calls to point to the deployed backend URL.
app.use(cors({
origin: 'https://your-frontend-url.vercel.app', // Replace with your Vercel URL
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true
}));- User authentication (JWT)
- Per-user notes
- Search & filtering
- Rich text editor
- Tagging system
This project includes both unit tests and integration tests to ensure reliability and correctness of the application. WE can also add end-to-end (E2E) tests in the future using tools like Cypress.
Unit tests focus on testing individual parts of the application in isolation.
- Controllers are tested independently
- Database calls (Mongoose) are mocked
- Ensures business logic works correctly
- Vitest
- Mocking with
vi.mock()
npm run testIntegration tests validate the complete request flow:
API routes Middleware Controllers Database interaction
These tests simulate real HTTP requests to the backend.
- Supertest
- Vitest
βΆοΈ Run Integration Tests
npm run testIf you like this project, consider giving it a β on GitHub!