What is Middleware in Express

Introduction
When building backend applications with Express.js, requests often need additional processing before reaching the final route handler.
Examples:
Logging requests
Authentication
Request validation
Parsing JSON
Error handling
Instead of writing this logic repeatedly inside every route, Express provides:
Middleware
Middleware is one of the most important concepts in Express.js.
In this article, we will learn:
What middleware is
Where middleware sits in the request lifecycle
Types of middleware
Execution order
Role of
next()Real-world middleware examples
What Is Middleware in Express?
Middleware is:
A function that runs between the request and the response.
Middleware can:
Read requests
Modify requests
Stop requests
Send responses
Pass control to the next middleware
Real-Life Analogy
Think of middleware like security checkpoints at an airport.
Passenger
│
▼
Security Check
│
▼
Passport Verification
│
▼
Boarding Gate
The passenger passes through multiple checkpoints before reaching the final destination.
Express middleware works similarly.
Middleware in Request Lifecycle
When a client sends a request:
Browser → Express Server
the request passes through middleware before reaching the route handler.
Request → Middleware → Route Handler Flow
Client Request
│
▼
Middleware 1
│
▼
Middleware 2
│
▼
Route Handler
│
▼
Response Sent
Basic Middleware Syntax
function middleware(req, res, next) {
}
Understanding Middleware Parameters
| Parameter | Meaning |
|---|---|
req |
Request object |
res |
Response object |
next |
Pass control to next middleware |
Why next() Is Important
next() tells Express:
"Continue to the next middleware."
Without next():
Request gets stuck
Route handler may never execute
Simple Middleware Example
const express = require("express");
const app = express();
function logger(req, res, next) {
console.log("Request received");
next();
}
app.use(logger);
app.get("/", (req, res) => {
res.send("Home Page");
});
app.listen(3000);
Execution Flow
When request comes:
Middleware runs
Logs message
next()calledRoute handler executes
Response sent
Middleware Execution Sequence
Incoming Request
│
▼
logger middleware
│
next()
│
▼
Route Handler
│
▼
Response
What Happens Without next()?
Example:
function middleware(req, res, next) {
console.log("Middleware running");
}
Problem:
Request never reaches route handler
Browser keeps loading
Types of Middleware in Express
Express provides different types of middleware.
Main types:
Application-level middleware
Router-level middleware
Built-in middleware
1. Application-Level Middleware
Application-level middleware applies to the entire app.
Defined using:
app.use()
Example
app.use((req, res, next) => {
console.log("Application middleware");
next();
});
This runs for all routes.
Application-Level Middleware Flow
Every Request
│
▼
Application Middleware
│
▼
Matching Route
2. Router-Level Middleware
Router-level middleware works only for specific routers.
Example
const router = express.Router();
router.use((req, res, next) => {
console.log("Router middleware");
next();
});
Why Router Middleware Is Useful
Useful for grouping related routes.
Example:
/admin routes
/user routes
/api routes
Each group can have separate middleware.
3. Built-In Middleware
Express provides built-in middleware.
Most common:
express.json()
Example
app.use(express.json());
This middleware parses incoming JSON requests.
Why Built-In Middleware Matters
Without:
express.json()
req.body will be undefined for JSON requests.
Multiple Middleware Execution Chain
Express can run multiple middleware functions in sequence.
Example
function middleware1(req, res, next) {
console.log("Middleware 1");
next();
}
function middleware2(req, res, next) {
console.log("Middleware 2");
next();
}
app.use(middleware1);
app.use(middleware2);
app.get("/", (req, res) => {
res.send("Home Page");
});
Output:
Middleware 1
Middleware 2
Multiple Middleware Execution Chain Diagram
Request
│
▼
Middleware 1
│
▼
Middleware 2
│
▼
Route Handler
│
▼
Response
Middleware Order Matters
Express executes middleware:
Top to bottom
Example
app.use(middleware1);
app.use(middleware2);
Execution order:
middleware1 → middleware2
Real-World Example: Logging Middleware
Logging middleware tracks incoming requests.
Logging Middleware Example
function logger(req, res, next) {
console.log(`\({req.method} \){req.url}`);
next();
}
app.use(logger);
Output:
GET /
POST /login
Real-World Example: Authentication Middleware
Authentication middleware protects routes.
Authentication Example
function auth(req, res, next) {
const isLoggedIn = true;
if (isLoggedIn) {
next();
} else {
res.send("Unauthorized");
}
}
Protected Route Example
app.get("/dashboard", auth, (req, res) => {
res.send("Dashboard");
});
Only authenticated users can access.
Real-World Example: Request Validation
Middleware can validate incoming data.
Validation Example
function validate(req, res, next) {
if (!req.body.name) {
return res.send("Name is required");
}
next();
}
Middleware Can End Requests
Middleware does not always need:
next()
It can directly send response.
Example:
res.send("Access denied");
Common Beginner Mistakes
1. Forgetting next()
Request gets stuck.
2. Wrong Middleware Order
Middleware order affects execution.
3. Sending Multiple Responses
Wrong:
res.send("Hello");
next();
Can cause errors.
Difference Between Middleware and Route Handler
| Middleware | Route Handler |
|---|---|
| Processes request | Sends final response |
Usually calls next() |
Usually ends request |
| Runs before route | Final destination |
Practical Use Cases
Middleware is heavily used for:
Authentication
Logging
Validation
File uploads
Error handling
Rate limiting
Best Practices
1. Keep Middleware Small
Each middleware should handle one responsibility.
2. Use Middleware Reusably
Avoid duplicate logic across routes.
3. Place Middleware Carefully
Execution order matters.
Mental Model
Think of middleware as workers in a factory pipeline.
Raw Request
│
▼
Worker 1 checks request
│
▼
Worker 2 validates request
│
▼
Worker 3 authenticates request
│
▼
Final response created
Each middleware performs one task before passing the request forward.
Full Working Example
const express = require("express");
const app = express();
app.use(express.json());
function logger(req, res, next) {
console.log(`\({req.method} \){req.url}`);
next();
}
function auth(req, res, next) {
const isLoggedIn = true;
if (isLoggedIn) {
next();
} else {
res.send("Unauthorized");
}
}
app.use(logger);
app.get("/", (req, res) => {
res.send("Home Page");
});
app.get("/dashboard", auth, (req, res) => {
res.send("Dashboard Page");
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});
Running the Server
node server.js
Testing Routes
Visit:
http://localhost:3000/
and
http://localhost:3000/dashboard
Conclusion
Middleware is one of the most powerful features of Express.js.
Key takeaways:
Middleware runs between request and response
Middleware processes requests before route handlers
next()passes control forwardExpress supports application, router, and built-in middleware
Middleware order matters
Middleware helps keep applications clean and reusable
Understanding middleware is essential because almost every real-world Express application depends heavily on middleware pipelines.

