Your first Express app

Express · Essentials · 8 min

Every Express app, however large, starts from these same few lines.

An Express app is created by calling express(). The result, conventionally named app, is both a request handler function and the object you configure.

  • app.get(path, handler) registers a route: when a GET request matches path, Express calls handler(req, res).
  • res.send(body) sends a response; it sets Content-Type from the body (HTML for strings, JSON for objects) and Content-Length, then ends the response.
  • app.listen(port, callback) creates a Node HTTP server and starts listening. It returns that http.Server, which you keep for shutting down later.

Read the port from the environment (process.env.PORT) so hosting platforms can choose it. In Express 5, if the server fails to start — for example the port is already in use (EADDRINUSE) — the error is passed to the listen callback, so check its first argument.

Run the app with node --watch server.js during development to restart on every save.

Two habits worth forming from day one:

  • Separate the app from the server. Export app from app.js and call listen in server.js. Tests can then use the app without opening a port.
  • Every request must get a response. If a handler neither sends a response nor passes control on, the client waits until it times out.

When nothing matches a request, Express answers with a default 404 page ("Cannot GET /nope"). You'll replace that with your own handler later.

Example

// app.js
import express from "express";

export const app = express();

app.get("/", (req, res) => {
  res.send("Hello from Express!");          // text/html; charset=utf-8
});

app.get("/health", (req, res) => {
  res.json({ status: "ok", uptime: process.uptime() });
});

// server.js — run: node --watch server.js
// import { app } from "./app.js";
const port = Number(process.env.PORT ?? 3000);
const server = app.listen(port, (err) => {
  if (err) throw err;                       // e.g. EADDRINUSE (Express 5)
  console.log(`listening on http://localhost:${port}`);
});

Remember

  • express() creates the app; app.get adds a route; app.listen starts a server
  • Keep app (exported) separate from listen for testability
  • Every request must end with a response

Watch out for

  • Hard-coding the port instead of reading process.env.PORT.

Check yourself

  1. A GET request arrives for a path with no matching route and no custom handler. What does the client get?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: expressjs.com/en/starter/hello-world