Skip to main content
Practice Problems

What are the different types of middleware in Express.js?

Types of Middleware in Express.js

Middleware functions are the backbone of Express.js. They have access to the req, res, and next objects. Express has five distinct types of middleware.


1. Application-level Middleware

Bound to the app object using app.use() or app.METHOD():

js
const express = require('express'); const app = express(); // Runs on EVERY request app.use((req, res, next) => { console.log(`${req.method} ${req.url} - ${Date.now()}`); next(); }); // Runs only for GET /users app.get('/users', (req, res, next) => { // ... next(); });

2. Router-level Middleware

Bound to a Router instance — works identically to application-level but scoped to a router:

js
const router = express.Router(); // Runs on every request to this router router.use((req, res, next) => { console.log('Router middleware'); next(); }); router.get('/profile', (req, res) => { res.json({ user: 'John' }); }); app.use('/api/users', router); // Middleware runs on: GET /api/users/profile

3. Error-handling Middleware

Has four parameters — Express recognizes it by the signature (err, req, res, next):

js
// Must have exactly 4 parameters! app.use((err, req, res, next) => { console.error(err.stack); if (err.name === 'ValidationError') { return res.status(400).json({ error: err.message }); } if (err.name === 'UnauthorizedError') { return res.status(401).json({ error: 'Unauthorized' }); } res.status(500).json({ error: 'Internal Server Error' }); });

Error middleware must be defined last, after all routes:

js
// Routes first app.use('/api/users', userRoutes); app.use('/api/products', productRoutes); // Then error handler app.use(errorHandler);

4. Built-in Middleware

Express has three built-in middleware functions:

js
// Parse JSON bodies app.use(express.json()); // Parse URL-encoded bodies app.use(express.urlencoded({ extended: true })); // Serve static files app.use(express.static('public'));

5. Third-party Middleware

Installed via npm:

js
const cors = require('cors'); const helmet = require('helmet'); const morgan = require('morgan'); const compression = require('compression'); app.use(cors()); // CORS headers app.use(helmet()); // Security headers app.use(morgan('dev')); // HTTP request logging app.use(compression()); // Gzip compression

Middleware Execution Order

Middleware executes in the order it's defined:

js
app.use(cors()); // 1st app.use(helmet()); // 2nd app.use(express.json()); // 3rd app.use(morgan('dev')); // 4th app.use('/api', routes); // 5th — route handlers app.use(notFoundHandler); // 6th — 404 handler app.use(errorHandler); // 7th — error handler (LAST)

Important Rules

RuleDescription
Always call next()Or the request hangs
Don't call next() after res.send()Causes "headers already sent" error
Error handler = 4 paramsMust have (err, req, res, next)
Order mattersDefine middleware before routes
Use next(err) to pass errorsSkips to error-handling middleware
js
// Passing errors to error handler app.get('/api/users/:id', async (req, res, next) => { try { const user = await User.findById(req.params.id); if (!user) { const err = new Error('User not found'); err.status = 404; return next(err); // Skip to error handler } res.json(user); } catch (err) { next(err); // Passes to error handler } });

Tip: Think of middleware as a pipeline. Each function either handles the request, passes it to the next function with next(), or short-circuits with next(err).

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems