What is Middleware in Express and How It Works

Learning web development in public. Writing simple, real-world explanations about web development concepts. Helping beginners understand why things work, not just how.
When building applications with Express, one concept you will see everywhere is middleware. It is one of the most important parts of how Express works.
If you understand middleware properly, you can control how requests are processed, validated, and handled in your application.
1. What Middleware is in Express
Middleware is simply a function that runs between the request and the response.
It has access to:
req(request)res(response)next(a function to move to the next step)
Basic structure:
function middleware(req, res, next) {
// do something
next();
}
Middleware can:
Modify request or response
Execute some logic
End the request-response cycle
Pass control to the next middleware
2. Where Middleware Sits in Request Lifecycle
When a client sends a request, it does not go directly to the route handler.
Instead, it passes through a chain of middleware functions.
Flow:
Request → Middleware → Middleware (if there in another one) → Route Handler → Response
Each middleware gets a chance to:
Process the request
Decide whether to continue or stop
3. Types of Middleware
Express provides different types of middleware based on how and where they are used.
a) Application-Level Middleware
These are applied to the entire app.
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log('App-level middleware');
next();
});
This runs for every request.
b) Router-Level Middleware
These are applied to specific routes using a router.
const router = express.Router();
router.use((req, res, next) => {
console.log('Router-level middleware');
next();
});
router.get('/users', (req, res) => {
res.send('Users route');
});
app.use('/api', router);
This runs only for routes under /api.
c) Built-in Middleware
Express provides some built-in middleware.
Examples:
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
These help in:
Parsing JSON
Handling form data
4. Execution Order of Middleware
Middleware runs in the order it is defined.
Example:
app.use((req, res, next) => {
console.log('First');
next();
});
app.use((req, res, next) => {
console.log('Second');
next();
});
app.get('/', (req, res) => {
res.send('Done');
});
Output:
First
Second
If the order changes, the behaviour also changes.
5. Role of next() Function
The next() function is used to pass control to the next middleware.
If you do not call next():
The request will stop
The client will not get a response (request hangs)
Example:
app.use((req, res, next) => {
console.log('Middleware running');
next();
});
You can also stop the flow:
app.use((req, res) => {
res.send('Request ended here');
});
6. Real-World Examples
Middleware is used in almost every backend application.
a) Logging
app.use((req, res, next) => {
console.log(`\({req.method} \){req.url}`);
next();
});
Logs every incoming request.
b) Authentication
function auth(req, res, next) {
const isLoggedIn = true;
if (!isLoggedIn) {
return res.status(401).send('Unauthorized');
}
next();
}
app.get('/profile', auth, (req, res) => {
res.send('Protected profile');
});
Only allows access if the user is authenticated.
c) Request Validation
app.post('/user', (req, res, next) => {
if (!req.body.name) {
return res.status(400).send('Name is required');
}
next();
}, (req, res) => {
res.send('User created');
});
Ensures correct data before processing.
Final Understanding
Middleware is a function that runs between request and response
It sits in the request lifecycle before the final handler
There are different types: application-level, router-level, and built-in
Middleware executes in order
next()controls the flowIt is used for logging, authentication, validation, and more
Summary
Middleware is the backbone of Express applications. It allows you to break down request handling into small, reusable steps that process data, enforce rules, and control application flow. By chaining middleware functions together, you can build scalable and maintainable systems. Whether it is logging requests, checking authentication, or validating input, middleware gives you full control over how your application behaves at every stage of a request.



