Build a Small To-Do Web App with Express and Vanilla JavaScript
Computer Science
Build a Small To-Do Web App with Express and Vanilla JavaScript
Build a Small To-Do Web App with Express and Vanilla JavaScript
Build a simple working to-do app from the ground up. You will create an Express server, serve a browser page, connect the page to the server with fetch, and add task listing and task creation without relying on a framework on the front end.
What you learn by building this
- Create and run a minimal Express server
- Serve an HTML, CSS, and JavaScript front end from Node.js
- Design and use GET and POST endpoints for basic task data
- Render tasks in the browser and add new tasks through a form
- Verify the finished app through visible browser behavior and endpoint checks
Learning Journey
Create the server and first visible page
2 lessonsStart with a small runnable project, then make Express serve a real browser page. The module ends with a page the learner can open and show.
Add task data and API routes
2 lessonsGive the app task data and a small API. The learner moves from a static page to a server that can return tasks and accept a new task.
Connect the browser to the API
3 lessonsTurn the page into a usable app by loading tasks from the server and sending new tasks from the form. The finished project is something the learner can run, use, and demonstrate.
Public lesson
Create the project and run a minimal server
Predict
What will happen?
Your first Node.js server with Express
You’re going to make a small program that listens for browser requests and sends back a clear response.
Before changing anything, predict this:
If a server is running but has no route for
/, what do you expect to see when you visit its address?
Keep that prediction in mind.
The important idea is that a server does not automatically produce a webpage. It waits for a request, matches that request to a route, and then sends a response.
Tasks
1. Check the project and Node.js
Open the existing practice project and inspect its files. Find package.json and read its "scripts" and "dependencies" sections.
In a terminal opened in the project, check that Node.js and npm are available:
node --version
npm --version
node --version
npm --version
You should see version numbers. Node.js runs JavaScript outside the browser; npm installs packages and records the project’s dependencies.
If package.json is not present, use the project’s documented command for creating or initializing the project. Do not replace an existing package.json, because it may contain settings the project needs.
Tasks
2. Install Express
Run:
npm install express
npm install express
Express is a library that makes the server’s request-and-response work easier to write. Without it, Node.js can still create a server, but you would need to handle more low-level details yourself.
After the command finishes, inspect package.json again. Confirm that:
expressappears under"dependencies"- npm may also have created or updated a lockfile
That change is important: the project now records that it depends on Express. Another person or machine can use that record to install the same dependency later.
Tasks
3. Write the server’s three responsibilities
Open the project’s server entry file, or create the entry file specified by the project instructions. The file needs to do three separate jobs:
- Import Express.
- Create an Express application.
- Start listening on a port.
It also needs one route so the browser receives a useful response.
Use this as a skeleton, filling in the missing values yourself:
const express = require("express");
const app = express();
app.get("/", (request, response) => {
response.send(/* a short message that identifies your server */);
});
const port = /* choose the port specified by the project, or use 3000 */;
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
const express = require("express");
const app = express();
app.get("/", (request, response) => {
response.send(/* a short message that identifies your server */);
});
const port = /* choose the port specified by the project, or use 3000 */;
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
Do not skip the distinction between request and response:
requestdescribes what the browser asked for.responseis what your server sends back.app.get("/", ...)means “when a browser makes a GET request for the root path/, run this function.”response.send(...)ends that request with text the browser can display.app.listen(...)makes the program wait for incoming connections.
The callback passed to app.get does not run when the file is merely loaded. It runs later, when a request actually arrives. That is why starting the program and visiting the browser are two different events.
Choose a message that makes the result unmistakable, such as a sentence containing the project’s purpose or your own name. A plain message is useful here because it proves the server response is coming from your code rather than from a browser error page.
Tasks
4. Start the server
Use the project’s documented start command. If the project does not define one, run Node with the server entry file you opened:
node <your-server-entry-file>
node <your-server-entry-file>
Replace the placeholder with the actual filename; do not type the angle brackets.
Leave this terminal running. A server that is listening has not finished like a short script—it is deliberately staying alive so it can receive requests.
Look at the terminal output. You should see the listening message from your app.listen callback.
Now open a browser and visit:
http://localhost:<your-port>
http://localhost:<your-port>
For example, if you chose port 3000, the address is:
http://localhost:3000
http://localhost:3000
You should see the message passed to response.send.
This is the complete request path:
The address has two meaningful parts:
localhostmeans “this same computer.”- The port identifies which listening program should receive the request.
Tasks
5. Verify that the route is doing the work
Change only the message inside response.send(...) while the server is still running. Save the file, then refresh the browser.
Observe what happens:
- If the new message appears, your route is responding.
- If the old message remains, your running Node process may not reload changed files automatically. Stop it with
Ctrl+C, start it again, and refresh. - If the browser cannot connect, inspect the terminal for an error and check that the browser’s port matches the port passed to
app.listen.
Then visit a different path, such as:
http://localhost:<your-port>/test
http://localhost:<your-port>/test
You will probably see an Express “Cannot GET” response. That is useful evidence: your server is reachable, but you only defined a route for /. A server can be running correctly while still having no handler for a particular path.
Return to / and confirm your intended message appears there.
What you should now be able to explain
A minimal Express server works because several pieces have different jobs:
npm install expressadds the library to the project’s dependencies.require("express")loads that library into the server file.express()creates an application object.app.get("/", ...)connects a URL path and HTTP method to your code.response.send(...)sends data back to the browser.app.listen(...)opens a port and keeps the Node.js process waiting for requests.
Stop the server with Ctrl+C when you are finished. Starting it again should produce the same browser response, because the project now has both a recorded Express dependency and a server entry file that uses it.
Course Outline
3 modules · 7 lessons
Create the server and first visible page
Add task data and API routes
Connect the browser to the API
Learn by building your own version.
Remix this public project to open the workspace, follow the guided build, and let the AI mentor teach you through the work instead of doing it for you.