Skip to main content

Command Palette

Search for a command to run...

What is Middleware in Express and How It Works

Published
5 min read
What is Middleware in Express and How It Works

When building applications with Express.js, one of the most important concepts you’ll encounter is middleware.
Middleware is what makes Express powerful, flexible, and easy to scale.

Whether it’s logging requests, checking authentication, validating input, or handling errors, middleware sits in the middle of the request-response cycle and controls how requests move through your application.

In this article, we’ll understand what middleware is, how it works internally, different types of middleware, and why it plays such a critical role in Express applications.


What is Middleware in Express?

Middleware in Express is simply a function that runs between receiving a request and sending a response.

It gets access to:

  • req → the incoming request

  • res → the response object

  • next() → a function that passes control to the next middleware

Basic syntax:

const middleware = (req, res, next) => {
    console.log("Middleware executed");

    next();
};

Middleware acts like a checkpoint in the request lifecycle.

Instead of sending every request directly to the route handler, Express allows middleware to inspect, modify, block, or process requests before they reach the final response.


Middleware in the Request Lifecycle

Here’s how a request typically flows in Express:


Client Request
      ↓
Middleware 1
      ↓
Middleware 2
      ↓
Middleware 3
      ↓
Route Handler
      ↓
Response Sent

Think of middleware as workers standing in a pipeline.

Each worker performs a task and then either:

  • passes the request forward using next()

  • stops the request and sends a response


Middleware Execution Flow

A middleware chain works sequentially.

Example:


app.use((req, res, next) => {
    console.log("First middleware");
    next();
});

app.use((req, res, next) => {
    console.log("Second middleware");
    next();
});

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

When a request hits /, the output becomes:

First middleware
Second middleware

Then the route handler sends the final response.


Role of next() Function

The next() function is extremely important in Express middleware.

It tells Express:

“Move to the next middleware or route handler.”

Example:

const logger = (req, res, next) => {
    console.log(req.method, req.url);

    next();
};

Without calling next(), the request gets stuck and never reaches the next step.

Example of a blocked request:

app.use((req, res, next) => {
    console.log("Request received");
});

Since next() is missing and no response is sent, the browser keeps loading forever.


Types of Middleware in Express

Express supports multiple types of middleware.

1. Application-Level Middleware

Application-level middleware is attached directly to the Express app using:

app.use()

Example:

app.use((req, res, next) => {
    console.log("Application middleware");
    next();
});

This middleware runs for every request unless restricted to a specific path.

Example with path:

app.use("/admin", (req, res, next) => {
    console.log("Admin middleware");
    next();
});

Now it only runs for routes starting with /admin.

2. Router-Level Middleware

Router-level middleware works specifically with Express routers.

Example:


const router = express.Router();

router.use((req, res, next) => {
    console.log("Router middleware");
    next();
});

This middleware only affects routes inside that router.

Useful for:

  • admin panels

  • API modules

  • authentication-protected sections

3. Built-in Middleware

Express already provides some middleware functions.

Example:

  • JSON Middleware
app.use(express.json());

This parses incoming JSON request bodies.

Without it:

req.body

would be undefined.

  • Static File Middleware
app.use(express.static("public"));

This serves static files like:

  • images

  • CSS

  • JavaScript files


Execution Order of Middleware

Middleware executes in the exact 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();
});

Output:

Middleware 1
Middleware 2

If the order changes, behavior changes too.

This is extremely important for things like:

  • authentication

  • body parsing

  • logging

  • validation

For example, body parsing middleware should run before validation middleware.


Real-World Middleware Examples

Middleware becomes powerful when used for common backend tasks.

Logging Middleware

Used to log request details.

Example:


app.use((req, res, next) => {
    console.log(`\({req.method} \){req.url}`);
    next();
});

Output:

GET /users
POST /login

This helps in debugging and monitoring traffic.

Authentication Middleware

Checks whether a user is authenticated.

Example :


const authMiddleware = (req, res, next) => {
    const token = req.headers.authorization;

    if (!token) {
        return res.status(401).json({
            message: "Unauthorized"
        });
    }

    next();
};

Protected route:


app.get("/profile", authMiddleware, (req, res) => {
    res.send("Protected Profile");
});

Request Validation Middleware

Validates incoming request data before processing.

Example:

const validateUser = (req, res, next) => {
    const { name, email } = req.body;

    if (!name || !email) {
        return res.status(400).json({
            message: "All fields are required"
        });
    }

    next();
};

Route usage:

app.post("/users", validateUser, (req, res) => {
    res.send("User created");
});

Why Middleware is So Important

Middleware is the backbone of Express applications.

It allows developers to:

  • separate logic cleanly

  • reuse functionality

  • create scalable APIs

  • control request flow efficiently

Almost every major backend feature in Express is implemented using middleware.

Examples include:

  • authentication

  • file uploads

  • request parsing

  • CORS handling

  • logging

  • rate limiting

  • error handling


Conclusion

Middleware is one of the most powerful concepts in Express.js.

It acts as a bridge between the incoming request and the final response, allowing you to process requests step by step.

By understanding:

  • how middleware works

  • execution order

  • the role of next()

  • different middleware types

you gain much better control over how your Express applications behave.

As your applications grow, middleware becomes essential for writing clean, organized, and maintainable backend code.