Express middleware explained, step by step
Middleware is a line of functions every request walks before your handler. Watch three stations stamp one request in order, then a missing token stop it early.

Every request walks the same line
Before your route handler runs, the request passes through a line of small functions, in the exact order you registered them.
Step 1 of 6
If you have written app.use(express.json()) without being sure what it does, or
watched req.body come back undefined for no reason you could see, this is the
idea you are missing. Middleware is not a plugin system. It is a line, and every
request walks it. Step through the scene above first.
The line, and the three powers of a station
Before your route handler runs, the request passes through every function you
registered with app.use, in the order you registered them. Each of those functions
is middleware, and each has the same shape: (req, res, next). Inside it, a station
can do exactly one of three things.
- Inspect and forward. Read the request, maybe attach something to it, then call
next()so the next station gets a turn. Parsers and loggers do this. - Answer. Send a response and stop. The request never reaches anything behind
this station. An auth check that returns
401does this. - Neither. Return without answering and without
next(). The request hangs forever. This is the bug, and it is silent.
app.use(express.json()); // 1: parses the body, sets req.body
app.use((req, res, next) => { // 2: logs, then forwards
console.log(req.method, req.url);
next();
});
app.use((req, res, next) => { // 3: verifies the token
const user = verify(req.headers.authorization);
if (!user) return res.sendStatus(401); // answers, line ends here
req.user = user;
next();
});
app.post("/books", (req, res) => { // the handler uses what the line left
const book = save({ ...req.body, ownerId: req.user.id });
res.status(201).json(book);
});
Order is behaviour, not style
Each station leaves something on the request for the stations behind it. The parser
leaves req.body. Auth leaves req.user. The handler at the end reads both and does
nothing but the work that makes that route unique. That is the whole point: write the
shared chore once, put it on the line, and every request passes through it.
It also means reordering the line changes what your server does. Move express.json
below the route and req.body is undefined when the handler runs. Move the logger
below auth and a rejected request never gets logged, because it left the line before
reaching the logger. And a station that answers unconditionally near the top silences
every route beneath it. The
Express guide to writing middleware
has the reference; the lesson lets you reorder the line, predict the result, and break
it both famous ways.
Common questions
- What happens if middleware never calls next()?
- The request hangs. It has entered a function that neither answered nor passed it on, so the client waits until it times out. Every middleware must either send a response or call next().
- Does the order I call app.use() in matter?
- Yes, completely. Registration order is execution order. Put express.json after a route and that route sees req.body as undefined, because it ran before the body was parsed.
- What is the difference between middleware and a route handler?
- Shape wise, nothing. Both are functions of (req, res, next). The difference is intent. Middleware does shared work and usually calls next(); a route handler does the unique work and sends the response.
- Can middleware run only for some routes?
- Yes. Pass it to app.use with a path prefix, or drop it directly into one route's argument list before the handler. It then sits on the line only for the requests that match.
Keep reading

401 vs 403, the difference in one request
401 means the server doesn't know who you are; 403 means it does, and the answer is no. Watch one request hit both gates.

How the Node event loop works, visually
Node runs on one thread yet never blocks. Watch one async callback wait in the queue and get pushed onto the call stack to see how.

HTTP status codes, the eight you need
You don't need dozens of status codes. Watch one request get 200, 301, 401, 404 and 500, learn the first digit rule, and keep the eight that cover real traffic.