What is Middleware in Express and How It Works

Introduction
Imagine entering an airport.
Before you board your flight, you pass through several checkpoints:
ticket verification
security scanning
passport checking
baggage validation
At every checkpoint, someone checks something before allowing you to continue.
Now imagine if airports skipped all of that completely.
Absolute chaos.
People carrying shampoo bottles the size of water tanks would casually walk onto planes.
That checkpoint system is basically how:
Middleware
works in Express.js.
Middleware sits between:
Request and Response
and performs tasks before the final route handler executes.
It can:
log requests
authenticate users
validate data
modify requests
block access
Middleware is one of the most important concepts in Express.
And once you understand it, backend applications suddenly feel much more organised and professional.
In this guide, you’ll learn:
what middleware is
where it sits in request lifecycle
types of middleware
execution order
the role of
next()real-world middleware examples
Let’s enter the airport.
What Is Middleware in Express?
Middleware is simply:
A function that runs between request and response
It gets access to:
request object (
req)response object (
res)next middleware function (
next)
Middleware can:
execute code
modify request/response
stop request
pass control forward
Think of middleware like checkpoints in a pipeline.
Middleware Basic Syntax
function middleware(req, res, next) {
console.log("Middleware running");
next();
}
Understanding the Parameters
req
Contains request data.
res
Controls response.
next()
Passes control to next middleware or route handler.
Very important.
Without next(), request gets stuck.
Like passenger trapped forever at airport security.
Where Middleware Sits in Request Lifecycle
Request lifecycle:
Client Request
↓
Middleware
↓
Route Handler
↓
Response
Middleware acts like middle checkpoint layer.
Hence the name:
Middleware
Very logical once you see it visually.
Request → Middleware → Route Handler Flow
Simple Middleware Example
const express = require("express");
const app = express();
app.use((req, res, next) => {
console.log("Request received");
next();
});
app.get("/", (req, res) => {
res.send("Home Page");
});
What Happens Here
When request arrives:
middleware runs
logs message
calls
next()route handler executes
response sent
Execution order matters heavily.
Understanding next() Function
next() tells Express:
“Move to next middleware or route.”
Without it:
Request hangs forever
Example:
app.use((req, res, next) => {
console.log("Checking request");
next();
});
If next() removed:
Browser keeps loading endlessly.
Very common beginner mistake.
Real-Life Analogy
Middleware
Airport security checkpoint.
next()
Permission to continue.
Request
Passenger travelling through system.
Very beginner-friendly mental model.
Middleware Execution Sequence
Middleware executes:
In the order it is defined
Example:
app.use((req, res, next) => {
console.log("Middleware 1");
next();
});
app.use((req, res, next) => {
console.log("Middleware 2");
next();
});
app.get("/", (req, res) => {
res.send("Done");
});
Output:
Middleware 1
Middleware 2
Then route handler executes.
Multiple Middleware Execution Chain
Why Middleware Is Powerful
Middleware allows developers to separate concerns cleanly.
Instead of writing same logic repeatedly inside routes:
Check auth
Validate request
Log requests
Middleware handles these centrally.
Much cleaner.
Much more scalable.
Much fewer headaches later.
Types of Middleware in Express
Express supports several middleware types.
1. Application-Level Middleware
Applied to entire application using:
app.use()
Example:
app.use((req, res, next) => {
console.log("App-level middleware");
next();
});
Runs for all routes.
2. Router-Level Middleware
Applied only to specific router.
Example:
router.use((req, res, next) => {
console.log("Router middleware");
next();
});
Useful for route grouping.
3. Built-In Middleware
Express provides built-in middleware.
Examples:
express.json()
express.static()
Very commonly used.
Example: express.json()
app.use(express.json());
This middleware parses incoming JSON data automatically.
Without it:
req.body undefined
Extremely important for APIs.
Real-World Middleware Example: Logging
Logging middleware tracks incoming requests.
Example:
app.use((req, res, next) => {
console.log(req.method, req.url);
next();
});
Output example:
GET /users
POST /login
Very useful for debugging.
Real-World Middleware Example: Authentication
Authentication middleware protects routes.
Example:
app.use((req, res, next) => {
const isLoggedIn = true;
if(isLoggedIn) {
next();
} else {
res.send("Access Denied");
}
});
Middleware can stop request entirely.
Very powerful.
Real-World Middleware Example: Request Validation
Middleware can validate incoming data.
Example:
app.use((req, res, next) => {
if(!req.body.email) {
return res.send("Email required");
}
next();
});
Prevents invalid data from reaching route handlers.
Very useful.
Middleware Pipeline Analogy
Imagine car wash station.
Car passes through stages:
water spray
soap cleaning
drying
polishing
Each step performs one task before next stage.
That’s middleware pipeline.
Each middleware handles one responsibility.
Built-In Middleware Example: Static Files
Example:
app.use(express.static("public"));
Allows Express to serve static files.
Very common.
Very important.
Very beginner-friendly.
Route-Specific Middleware
Middleware can also apply to specific route only.
Example:
app.get("/admin", authMiddleware, (req, res) => {
res.send("Admin Panel");
});
Only this route uses authentication middleware.
Very flexible system.
Middleware Can Modify Request
Middleware can add custom properties.
Example:
app.use((req, res, next) => {
req.user = "Rahul";
next();
});
Later routes can access:
req.user
Very common practice.
Common Beginner Mistake
Biggest beginner mistake:
Forgetting next()
Example:
app.use((req, res, next) => {
console.log("Middleware");
});
No response.
No next.
Request hangs forever.
Very confusing initially.
Another Common Mistake
Sending multiple responses accidentally.
Example:
res.send("Error");
next();
Once response sent:
Request should end
Important rule.
Why Middleware Makes Express Powerful
Middleware gives Express enormous flexibility.
Developers can:
organise logic cleanly
reuse functionality
build scalable systems
separate responsibilities elegantly
Most Express architecture revolves around middleware pipelines.
It’s one of the framework’s biggest strengths.
Real-Life Analogy Recap
Request
Passenger entering airport.
Middleware
Security checkpoints.
next()
Permission to continue journey.
Route Handler
Final destination gate.
Simple flow.
Huge clarity improvement.
Unique Tip for Beginners
When debugging Express applications, always mentally trace:
Request → Middleware → Route → Response
That one habit solves a huge percentage of beginner confusion.
Final Thoughts
Middleware is one of the core concepts behind Express.js.
It sits between:
incoming requests
outgoing responses
and allows applications to:
log activity
authenticate users
validate data
process requests cleanly
Using:
application-level middleware
router middleware
built-in middleware
next()sequencing
Express applications become modular, organised, and scalable.
At a high level:
Middleware is the checkpoint system controlling request flow.
And once you understand that request pipeline, Express architecture suddenly feels far less mysterious and much more manageable.