Tricky Talks (or TWS Blog)
Level Up Your Skills with the Latest in Coding, AI, and Cloud
Learn MERN Stack Development: Build a Full-Stack To-Do App from Scratch
- Posted By: trickywebsolutions
-
June 13, 2025

A To-Do list web application that is built with the MERN stack (MongoDB, Express.js, Node.js, and React.js) is a project that represents simple CRUD operations. Users can carry out some fundamental operations, such as activities like create, read, update, and delete. The web app also enables the setting of deadlines for tasks so that users are aware of the last date to accomplish each task. In this blog, we will guide you through the process of developing one of the MERN stack projects, i.e., a to-do app from scratch. This is one of the basic MERN stack projects. We will also understand and learn what is MERN stack development.
But before you start developing your basic MERN stack projects, make sure you have a clear understanding of basic front-end fundamentals, including HTML, CSS, JavaScript, and some basic frameworks and libraries. However, we are hoping that by the end of this blog, you will successfully create a working To-Do app using the MERN Stack.
What is MERN Stack Development?
This technology combines four more technologies, which are MongoDB, Express.js, React.js, and Node.js, to build scalable web apps. Each technology plays a key role and has some specific responsibilities, such as MongoDB is assigned to store the data in databases in JSON format, Express.js is a backend framework that helps developers build API’s with its prebuilt features, react.js enables developers create attractive UIs and lastly Node.js allows them to run on server allowing seamless interaction of front end and back end. Moreover, all these technologies combined together make it an ideal choice for building basic MERN stack projects.
Technologies Required
Before you start, make sure you have a basic understanding of the following technologies, which are required to build this project.
MongoDB
Express JS
React JS
Node JS
HTML, CSS, JavaScript
Prerequisites:
Node.js must be installed on your system.
MongoDB should be set up either locally or through MongoDB Atlas.
A code editor (VS Code is recommended).
Approach to Building the To-Do List
On the client side, the “Todo” React component is used to display tasks, their deadlines, and status, along with a form for adding new to-do items, and features to edit or delete them.
On the backend, the application retrieves data from MongoDB, and new entries can be inserted into the database through APIs. Moreover, through the API, we can also make changes and remove a particular record from the table.
Functionalities of the To-Do Application
We will build a basic to-do list application that allows users to perform the following tasks:
Add a task: Enables users to create and submit a latest task.
View all tasks: The user can view the to-do list displayed in a table format.
Edit a Task: Pressing the “Edit” button makes the respective table row editable. When “Edit” is clicked, two new buttons named “Save” and “Reset” are displayed. Additionally, the “Save” button saves the altered data to the database, and the “Reset” button restores the field to its previous value.
Mark a task as completed: Once the task is complete user can mark it as complete.
Delete a task: The user may click the “Delete” button within the table to remove the information from the database.
The frontend will be built with React, while the backend API will be handled by Node.js and Express. MongoDB will store the tasks.
How to Build a Full-Stack To-Do App from Scratch: Step-by-Step Guide
Below we have listed the steps used to build full-stack To-Do from scratch:
Step 1: Setting Up the Project Structure
Start by creating a root project folder named mern-todo-app.
mern-todo-app/
|-- backend/
|-- frontend/
Navigate into each folder and initialize the projects.
Backend Setup
Navigate to the backend/ folder and initialize a new Node project:
npm init -y
npm install express mongoose cors dotenv
Create the essential files:
server.js: Entry point of the backend
models/Todo.js: Mongoose model
routes/todos.js: Routes for handling API requests
server.js
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
require('dotenv').config();
const todoRoutes = require('./routes/todos');
const app = express();
const PORT = process.env.PORT || 5000;
app.use(cors());
app.use(express.json());
app.use('/todos', todoRoutes);
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => app.listen(PORT, () => console.log(`Server running on port ${PORT}`)))
.catch((err) => console.log(err));
models/Todo.js
const mongoose = require('mongoose');
const TodoSchema = new mongoose.Schema({
title: { type: String, required: true }, // Task title, must be provided
completed: { type: Boolean, default: false }, // Task completion status, false by default
createdAt: { type: Date, default: () => Date.now() } // Timestamp when task is created
});
module.exports = mongoose.model('Todo', TodoSchema);
routes/todos.js
const express = require('express');
const router = express.Router();
const Todo = require('../models/Todo');
router.get('/', async (req, res) => {
const todos = await Todo.find();
res.json(todos);
});
router.post('/', async (req, res) => {
const newTodo = new Todo({ title: req.body.title });
await newTodo.save();
res.json(newTodo);
});
router.put('/:id', async (req, res) => {
const updated = await Todo.findByIdAndUpdate(req.params.id, { completed: req.body.completed }, { new: true });
res.json(updated);
});
router.delete('/:id', async (req, res) => {
await Todo.findByIdAndDelete(req.params.id);
res.json({ message: 'Deleted successfully' });
});
module.exports = router;
Frontend Setup
Navigate to the frontend/ folder:
npx create-react-app .
npm install axios react-router-dom
Create the following components:
AddTodo.js
TodoList.js
TodoItem.js
App.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import AddTodo from './components/AddTodo';
import TodoList from './components/TodoList';
function App() {
const [todos, setTodos] = useState([]);
useEffect(() => {
axios.get('/todos').then(res => setTodos(res.data));
}, []);
const addTodo = (title) => {
axios.post('/todos', { title }).then(res => setTodos([...todos, res.data]));
};
with this const toggleTodo = (id, completed) => {
axios.put(`/todos/${id}`, { completed }).then(res => {
setTodos(todos.map(todo => (todo._id === id ? res.data : todo)));
});
};
const deleteTodo = (id) => {
axios.delete(`/todos/${id}`).then(() => {
setTodos(todos.filter(todo => todo._id !== id));
});
};
return (
const todoProps = { todos, toggleTodo, deleteTodo };
);
}
export default App;
Step 6: Deployment
You can deploy the backend on platforms like Render, Railway, or Heroku, and the frontend on Netlify or Vercel.
Make sure you update API URLs accordingly in your frontend axios calls when moving to production.
Conclusion
In conclusion, building a full-stack To-Do app using the MERN stack is a great way to gain hands-on experience with modern MERN stack development tools. Moreover, through this project, you’ve covered the fundamentals of frontend and backend development, RESTful APIs, database integration, and full-stack deployment workflows. This practical experience forms a strong foundation for more complex applications and professional projects.