Skip to content

Express Middleware

Middleware is the single most important concept in Express, almost everything the framework does, parsing bodies, logging, authentication, error handling, is implemented as middleware. This lesson explains what middleware is and how it chains together.

What Is Middleware?

Middleware is simply a function with the signature (req, res, next) that sits in the request-handling pipeline. It can inspect or modify req/res, end the request-response cycle by sending a response, or call next() to pass control to the next function in line.

A route handler is itself a special kind of middleware, scoped to a specific method and path, that usually ends the cycle rather than calling next().

function logger(req, res, next) {
  console.log(`${req.method} ${req.url}`);
  next(); // pass control to the next middleware/route
}

app.use(logger);

app.get('/', (req, res) => {
  res.send('Home');
});

Every request first runs through logger, which logs and calls next(), then reaches the / route handler.

The Middleware Signature

function middleware(req, res, next) {
  // ... do something ...
  next(); // continue to the next middleware/route
}

// error-handling middleware has 4 arguments
function errorHandler(err, req, res, next) {
  // ...
}
  • Regular middleware takes exactly three arguments: req, res, next.
  • Calling next() with no arguments continues to the next matching function.
  • Calling next(err) skips ahead to error-handling middleware.
  • Not calling next() and not sending a response leaves the request hanging forever.

Middleware Cheatsheet

The different ways middleware gets registered in Express.

Type Example Scope
Application-level app.use(fn) Every request
Path-scoped app.use('/admin', fn) Requests under /admin
Router-level router.use(fn) Requests handled by that router
Route-level app.get('/x', mw1, mw2, handler) Just that one route
Built-in express.json() Parses JSON bodies
Third-party cors(), helmet() From npm packages
Error-handling (err, req, res, next) => {} Runs only when next(err) is called

The Middleware Chain

You can register any number of middleware functions, and Express executes them strictly in the order they were added. This chain-of-responsibility pattern is what lets you compose small, focused functions, one for logging, one for auth, one for validation, instead of one giant handler.

app.use(loggerMiddleware);
app.use(express.json());
app.use(authMiddleware);

app.get('/orders', requireAdmin, listOrders);

/orders runs through loggerMiddleware, express.json(), authMiddleware, then requireAdmin, before finally reaching listOrders.

The Five Types of Middleware

Express documentation groups middleware into five categories, and this course covers each in its own lesson: application-level, router-level, error-handling, built-in, and third-party.

  • Application-level: bound to the app object with app.use()/app.METHOD().
  • Router-level: bound to an express.Router() instance the same way.
  • Error-handling: takes four arguments, (err, req, res, next).
  • Built-in: ships with Express itself, e.g. express.json(), express.static().
  • Third-party: installed from npm, e.g. cors, helmet, morgan.

Common Mistakes

  • Forgetting to call next(), causing the request to hang with no response and no error.
  • Calling next() after already sending a response, causing a "headers already sent" error.
  • Registering middleware after the routes that need it, so it never runs in time.
  • Writing an error-handling middleware with only three parameters, Express will treat it as regular middleware.

Key Takeaways

  • Middleware is any function with the (req, res, next) signature placed in the request pipeline.
  • Middleware either ends the cycle with a response or calls next() to continue.
  • Order of registration determines execution order.
  • Express groups middleware into application-level, router-level, error-handling, built-in, and third-party.

Pro Tip

When a route seems to hang forever with no error, check every middleware in its chain for a missing next() call, it is the single most common cause of a stuck request in Express.