Skip to content

Express.js for Node.js Developers

Express is the most widely used web framework for Node.js. After building routing and middleware by hand in the previous lessons, this lesson shows how Express packages those exact patterns into a clean, production-ready API.

What Is Express.js?

Express is a minimal, unopinionated web framework built directly on top of Node's http module. It replaces the manual routing and middleware pipeline you built earlier in this course with a small, chainable API: app.get(), app.post(), app.use(), plus a richer req/res object with convenience methods like res.json() already built in.

Because it's unopinionated, Express doesn't dictate your project structure, database, or templating engine, you pick those yourself and Express focuses purely on routing and middleware, which is exactly why it remains a default choice across the Node.js ecosystem.

import express from 'express';

const app = express();

app.use(express.json());

app.get('/', (req, res) => {
  res.json({ message: 'Hello from Express!' });
});

app.listen(3000, () => {
  console.log('Server listening on port 3000');
});

Compare this to the raw http.createServer() version from earlier lessons, Express removes the manual method/URL branching and gives you res.json() directly.

Core Express API

const app = express();
app.use(middleware);
app.get('/path', handler);
app.post('/path', handler);
app.listen(port);
  • express() creates an application instance, the equivalent of your custom router from earlier lessons.
  • app.use() registers middleware for all matching requests, mirroring the middleware pattern you already know.
  • app.get()/app.post()/etc. register method-specific route handlers.
  • app.listen() starts the underlying http server, exactly like server.listen() in raw Node.js.

Express Quick Reference

How Express concepts map onto what you already built by hand.

Raw Node.js Concept Express Equivalent
Manual method/URL branching app.get('/path', handler)
Custom middleware pipeline app.use(middleware)
Manual body parsing express.json() middleware
res.end(JSON.stringify(x)) res.json(x)
Manual static file serving express.static('public')
server.listen(port) app.listen(port)

Express Builds Directly on http

Under the hood, app.listen() calls http.createServer() and passes your Express app as the request handler. The req/res objects you receive in an Express route are the same http.IncomingMessage/http.ServerResponse objects from earlier lessons, just extended with extra convenience methods and properties.

  • res.json(), res.send(), and res.status() are Express additions on top of the base res object.
  • req.params, req.query, and req.body are Express additions on top of the base req object.
  • Everything you learned about streams, headers, and status codes still applies directly.

Express 4 vs Express 5

Express 4 has been the stable, dominant version for years. Express 5 became the npm default in 2024, removing long-deprecated APIs while keeping the same routing and middleware model. For the concepts in this course, the two versions are practically identical.

Common Mistakes

  • Thinking Express replaces Node.js, it's a library that runs on top of the Node.js runtime, not a separate runtime itself.
  • Forgetting express.json() middleware, leaving req.body undefined on JSON requests.
  • Assuming Express includes a database or templating engine by default, both are opt-in additions.
  • Applying old Express 3.x tutorials' patterns, some APIs from that era have since been removed.

Key Takeaways

  • Express is a minimal framework built directly on top of Node's http module.
  • It replaces manual routing and middleware pipelines with a clean, chainable API.
  • req/res in Express are the same Node.js stream-based objects, extended with convenience methods.
  • Express is unopinionated about database, templating, and project structure choices.

Pro Tip

Keep the raw http mental model from earlier lessons close by. Whenever an Express behavior feels surprising, remembering that req/res are still plain Node.js stream objects underneath usually clears up the confusion immediately.