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

JavaScriptNode.jsExpress

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.

3 modules7 lessonsComputer ScienceJavaScriptNode.jsExpressHTMLCSSFetch APInpm

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

1

Create the server and first visible page

2 lessons

Start 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.

2

Add task data and API routes

2 lessons

Give 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.

3

Connect the browser to the API

3 lessons

Turn 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

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

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:

  • express appears 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:

  1. Import Express.
  2. Create an Express application.
  3. 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}`);
});

Do not skip the distinction between request and response:

  • request describes what the browser asked for.
  • response is 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>

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>

For example, if you chose port 3000, the address is:

http://localhost:3000

You should see the message passed to response.send.

This is the complete request path:

The address has two meaningful parts:

  • localhost means “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

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 express adds 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.