🧑💻 Build a Simple TODO App with Express.js – Beginner’s Guide

Hello fellow devs! 👋
After spending way too much time in the HTML/CSS/JS loop for the past year, I decided it was finally time to break out and dive into backend development. 🚀 This is the first real backend project I’ve worked on, and it’s a TODO app built with Node.js + Express.js.
If you’re a beginner like me, this article will guide you step-by-step in creating your first Express.js app. Let’s go!
🧱 Tech Stack:
Node.js
Express.js
File System (
fs
) for storing data in JSON files
🔥 Features of the App:
User Signup (
POST /signup
)User Login (
POST /login
)View Tasks (
GET /tasks
)Add Tasks (
POST /tasks
)Delete Tasks (
DELETE /tasks
)
🧑💻 Setup
Before we get started, make sure you have Node.js installed. If not, head over to Node.js official website to download it.
Create a new folder for your project and initialize it with npm:
mkdir express-todo-app
cd express-todo-app
npm init -y
npm install express
🧑💻 Step-by-Step Code Breakdown
1. Setting Up Express
In your index.js
(or index2.js
), we’ll start by setting up the Express server and importing the necessary modules:
const fs = require("fs");
const express = require("express");
const app = express();
const path = require("path");
const PORT = 3001;
app.use(express.json()); // Here, we're also setting up JSON parsing with express.json() middleware.
2. Signup Route
Let’s allow users to sign up. The POST /signup
route will handle user creation:
app.post("/signup", (req, res) => {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).send("Username and password are required");
}
fs.readFile("user.json", "utf-8", function (err, data) {
let users = [];
if (err && err.code !== "ENOENT") {
return res.status(500).send("Error reading user file");
}
if (!err) {
try {
users = JSON.parse(data);
} catch (parseErr) {
return res.status(500).send("Error parsing user data");
}
}
if (users.find((user) => user.username === username)) {
return res.status(400).send("Username already exists");
}
users.push({ username, password });
fs.writeFile("user.json", JSON.stringify(users, null, 2), (err) => {
if (err) return res.status(500).send("Error saving user");
res.status(201).send("User created successfully");
});
});
});
3. Login Route
Here, we authenticate users when they try to log in:
app.post("/login", (req, res) => {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).send("Username and password are required");
}
fs.readFile("user.json", "utf-8", function (err, data) {
if (err) return res.status(500).send("Error reading user file");
let users = [];
try {
users = JSON.parse(data);
} catch (parseErr) {
return res.status(500).send("Error parsing user data");
}
const user = users.find(
(user) => user.username === username && user.password === password
);
if (!user) {
return res.status(400).send("Invalid credentials");
}
res.send("Login Successful");
});
});
4. Get Tasks for User
Once logged in, a user can fetch their tasks:
app.get("/tasks", (req, res) => {
const { username } = req.body;
if (!username) {
return res.status(400).send("Username is required");
}
fs.readFile("todo2.json", "utf-8", function (err, data) {
if (err && err.code !== "ENOENT") {
return res.status(500).send("Error reading tasks file");
}
let tasks = [];
if (!err) {
try {
tasks = JSON.parse(data);
} catch (parseErr) {
return res.status(500).send("Error parsing tasks data");
}
}
const userTasks = tasks.filter((task) => task.username === username);
res.json(userTasks);
});
});
5. Add and Delete Tasks
The app also lets users add and delete tasks:
app.post("/tasks", (req, res) => {
const { username, task } = req.body;
// Add task logic
});
app.delete("/tasks", (req, res) => {
const { username, task } = req.body;
// Delete task logic
});
// Both operations read and write to todo2.json to store tasks.
💡 What I Learned
Setting up a backend server with Express.js and Node.js
Working with file system (
fs
) for mock data storageCreating RESTful APIs for user authentication and task management
Handling JSON data and error handling in Express
🚀 What’s Next?
Add authentication using JWT
Switch from JSON files to a real MongoDB database
Build a React frontend for this app
🔗 Check out my code on GitHub:
Feel free to leave any questions or suggestions below. Happy coding! ✨
Subscribe to my newsletter
Read articles from Skanda Prasad D directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
