Express.js

Express.js is a minimal, unopinionated web framework for Node.js. It provides routing, middleware, and request/response helpers on top of Node's built-in HTTP server — and deliberately little else, leaving database access, validation, and project structure up to you.

That minimalism is why Express remains the most widely deployed Node.js framework: it is easy to learn, has a massive middleware ecosystem, and nearly every Node.js tutorial, hosting platform, and API example assumes it. If you understand Express, you can read most Node.js server code in the wild.

TL;DR

Quick Example

A complete REST API with JSON parsing, a route parameter, and error handling:

Core Concepts

Middleware

Middleware functions run in the order they're registered and can inspect or modify the request, end the response, or pass control to the next function. This single abstraction covers logging, auth, parsing, compression, and CORS.

The rules to remember:

Routing

Routes match an HTTP method plus a URL pattern. Path segments prefixed with : become parameters:

express.Router() groups related routes into mountable modules:

Request and Response

Async Handlers and Errors

The classic Express footgun: in Express 4, a rejected promise inside a handler is not caught — the request hangs and the error is swallowed.

Express 5 forwards rejected promises to the error middleware automatically, so the first version above is safe. If you're on Express 4, either wrap handlers in try/catch, use a tiny helper, or upgrade.

Project Structure

Express doesn't impose one, but this layered layout scales well and keeps handlers thin:

Separating app.js from server.js lets tests import the app without opening a port — Supertest can drive it directly.

Best Practices

Validate Input at the Edge

Never trust req.body. Validate against a schema before it reaches business logic:

Harden the Basics

Add rate limiting on auth and write endpoints, and serve everything over HTTPS.

Centralize Error Responses

One error middleware, registered after all routes, decides what clients see:

Don't Block the Event Loop

Node runs your handlers on a single thread. CPU-heavy work (image processing, crypto, large JSON transforms) freezes every request. Push that work to background jobs or worker threads.

Express vs Alternatives

Express trades raw speed and built-in structure for simplicity and the largest middleware ecosystem. For most CRUD APIs the framework is never the bottleneck — the database is.

Common Mistakes

Forgetting to Send or Forward

Registering Middleware After Routes

Sending Two Responses

FAQ

Is Express still worth learning?

Yes. It remains the most used Node.js framework by a wide margin, most Node.js documentation and middleware target it, and frameworks like NestJS build on top of it. Its concepts (routing, middleware chains) transfer directly to nearly every other web framework.

What's the difference between Express 4 and Express 5?

Express 5 is a long-awaited modernization: rejected promises in async handlers are forwarded to error middleware automatically, some deprecated APIs were removed, and path matching was updated. Migration from 4 is mostly mechanical.

Should I use Express or Fastify?

Fastify is faster at raw JSON throughput and has built-in schema validation; Express has the bigger ecosystem and more familiarity. For most applications either is fine — pick Fastify for performance-sensitive JSON APIs, Express for maximum compatibility.

How do I serve static files?

app.use(express.static("public")) serves files from the public directory. In production, prefer a CDN or Nginx in front of Node for static assets.

How do I structure a large Express app?

Split routes into express.Router() modules, keep business logic in framework-agnostic service files, and reserve controllers for request/response translation. See the project structure section above.

Related Topics

References