A full-stack note-taking application built with the MERN stack (MongoDB, Express, React, Node.js) and fully Dockerized for seamless development and deployment.
- Full-Stack App built with the MERN stack
- Create, Update, and Delete notes with title and content
- Fully Responsive UI with a dark forest-green theme
- Rate Limiting ready (Upstash Redis dependencies installed)
- RESTful API with proper HTTP methods and status codes
- Docker Compose setup for one-command development environment
Dockerization/
├── backend/ # Express.js REST API
├── frontend/ # React + Vite SPA
├── docker-compose.yml
└── README.md
The backend is a RESTful API built with Express.js and connected to MongoDB via Mongoose.
- Runtime: Node.js (ES Modules)
- Framework: Express.js v4
- Database: MongoDB (Mongoose ODM v8)
- Architecture: MVC-like (Model → Controller → Route)
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/notes |
Fetch all notes (newest first) |
GET |
/api/notes/:id |
Fetch a single note by ID |
POST |
/api/notes |
Create a new note |
PUT |
/api/notes/:id |
Update a note by ID |
DELETE |
/api/notes/:id |
Delete a note by ID |
{
"title": "String (required)",
"content": "String (required)",
"createdAt": "Date (auto-generated)",
"updatedAt": "Date (auto-generated)"
}backend/
├── src/
│ ├── server.js # Entry point: app setup, middleware, routes, DB connect
│ ├── config/db.js # MongoDB/Mongoose connection logic
│ ├── controllers/
│ │ └── notesController.js # Business logic for CRUD operations
│ ├── models/
│ │ └── Note.js # Mongoose schema and model
│ └── routes/
│ └── notesRoutes.js # Express Router → HTTP verbs to controllers
├── Dockerfile
├── .env
└── package.json
npm run dev # Start with nodemon (development)
npm start # Start with node (production)The frontend is a React 19 SPA built with Vite and styled with Tailwind CSS + DaisyUI.
- Framework: React 19 with functional components & hooks
- Build Tool: Vite 6
- Styling: Tailwind CSS 3 + DaisyUI (forest theme)
- Icons: Lucide React
- Notifications: React Hot Toast
- HTTP Client: Axios
| Route | Page | Description |
|---|---|---|
/ |
HomePage | Displays all notes in a responsive grid |
/create |
CreatePage | Form to create a new note |
/note/:id |
NoteDetailPage | View, edit, and delete a single note |
| Component | Description |
|---|---|
Navbar |
Header with app title and "New Note" button |
NoteCard |
Card displaying note title, content preview, date, and action icons |
NotesNotFound |
Empty state shown when no notes exist |
RateLimitedUI |
Warning banner for HTTP 429 rate-limit responses |
frontend/
├── src/
│ ├── main.jsx # Entry point: renders App with Router + Toaster
│ ├── App.jsx # Root component: global background, routes
│ ├── index.css # Tailwind directives
│ ├── components/
│ │ ├── Navbar.jsx
│ │ ├── NoteCard.jsx
│ │ ├── NotesNotFound.jsx
│ │ └── RateLimitedUI.jsx
│ ├── pages/
│ │ ├── HomePage.jsx
│ │ ├── CreatePage.jsx
│ │ └── NoteDetailPage.jsx
│ └── lib/
│ ├── axios.js # Axios instance (VITE_API_URL)
│ └── utils.js # formatDate() helper
├── Dockerfile
├── .env
├── vite.config.js
├── tailwind.config.js
└── package.json
npm run dev # Start Vite dev server (port 5173)
npm run build # Build for production
npm run preview # Preview production build
npm test # Run testsThe entire stack is orchestrated with Docker Compose running 3 services:
| Service | Image | Port | Description |
|---|---|---|---|
api |
node:20-alpine |
4000 |
Express.js backend |
web |
node:20-alpine |
5173 |
React/Vite frontend |
db |
mongo |
27017 |
MongoDB database |
# Start all services
docker-compose up
# Start in background
docker-compose up -d
# Stop all services
docker-compose down| Variable | Service | Description |
|---|---|---|
PORT |
api | Backend port (default: 4000) |
MONGO_URI |
api | MongoDB connection string |
MONGO_INITDB_ROOT_USERNAME |
db | MongoDB admin username |
MONGO_INITDB_ROOT_PASSWORD |
db | MongoDB admin password |
MONGO_URI=<your_mongo_uri>
NODE_ENV=development
VITE_API_URL=http://localhost:4000/api
Backend:
cd backend
npm install
npm run devFrontend:
cd frontend
npm install
npm run devThe frontend includes a Jest + Testing Library test for the CreatePage component:
cd frontend
npm test- In development mode, CORS is enabled for the frontend dev server (
localhost:5173). - In production mode, the backend serves the frontend's built static files (same origin, no CORS needed).
- MongoDB data is persisted via a Docker volume (
db-data).