You already understand the middleware pattern conceptually. This lesson shows exactly how Express implements it, application-level, router-level, and built-in middleware, and how they compose.
Middleware in Express
In Express, middleware is any function with the signature (req, res, next) registered via app.use() or a route method. It runs for every matching request, in the order it was registered, and either calls next() to continue the pipeline or sends a response itself.
Express ships several built-in middleware functions, most importantly express.json() for parsing JSON bodies and express.static() for serving files, and the ecosystem provides thousands more as npm packages (cors, helmet, morgan, and others covered later in this course).
Express walks through registered middleware and routes in the exact order they were added to the app, calling each one's next() to advance. Middleware needed by later steps, like body parsing before a route reads req.body, must be registered earlier in the file.
app.use(express.json()); // 1. parse body first
app.use(requireApiKey); // 2. then check auth (can read parsed body if needed)
app.post('/orders', createOrder); // 3. route runs last
Writing Your Own Middleware
Custom middleware is just a regular function, the same (req, res, next) signature you built by hand earlier in this course, now plugged into Express's pipeline instead of a hand-rolled one.
function requestTimer(req, res, next) {
req.startTime = Date.now();
next();
}
function logDuration(req, res, next) {
res.on('finish', () => {
console.log(`${req.method} ${req.url} took ${Date.now() - req.startTime}ms`);
});
next();
}
app.use(requestTimer, logDuration);
Common Mistakes
Registering body-parsing middleware after the routes that need req.body, leaving it undefined.
Forgetting to call next() inside custom middleware, silently stalling the request.
Calling next() after already sending a response, triggering "headers already sent" errors.
Registering security middleware like helmet()/cors() too late, after routes have already run.
Key Takeaways
Express middleware shares the same (req, res, next) signature you learned in the middleware basics lesson.
app.use() registers middleware for all requests or a specific path prefix.
Middleware order matters, dependencies (like body parsing) must be registered before code that needs them.
Built-in and third-party middleware cover most cross-cutting concerns without custom code.
Pro Tip
Group your middleware registration into a predictable order at the top of your app file: security first (helmet, cors), then logging, then body parsing, then your own auth checks, then routes. A consistent order across projects makes debugging pipeline issues much faster.
You now understand Express middleware deeply. Next, learn how Express handles errors consistently across an entire application.