4.22.1

Latest release in branch 4
Released 01 Dec 2025 (5 months ago)

SoftwareExpress
Branch4
Initial release4.0.0
09 Apr 2014 (12 years ago)
Latest release4.22.1
01 Dec 2025 (5 months ago)
Minimum
Node.js version
0.10.0
End of support (OSS)TBD (Supported)
Release noteshttps://github.com/expressjs/express/releases/tag/v4.22.1
Source codehttps://github.com/expressjs/express/tree/v4.22.1
Downloadhttps://github.com/expressjs/express/releases/tag/v4.22.1
Express 4 ReleasesView full list

What Is New in Express 4

Feature Category
Bundled middleware removed from core Breaking Change
app.use(app.router) no longer needed Breaking Change
New express.Router class New Feature
New app.route() shortcut New Feature
Route definitions respect call order automatically Improvement

Why does Express 4 no longer bundle middleware?

Express 4 stopped bundling any Connect middleware because the core team wanted to keep the framework lightweight and let npm handle updates.

In practice you now list each piece (body-parser, cookie-parser, etc.) in package.json and install it separately. This means security patches land faster and you only ship what you actually use.

How do I replace the old app.use(app.router) pattern?

You no longer call app.use(app.router); routes are added in the exact order you declare them.

Because Express now respects declaration order, mixing middleware and route handlers works intuitively:

app.get('/', home);
app.use('/public', require('st')(process.cwd()));
app.get('/users', users.list);
app.post('/users', users.create);

Think of it as a single queue: each app.use or verb pushes a handler onto the tail, and requests flow through that queue.

What is the app.route() shortcut and how does it simplify code?

app.route() lets you chain HTTP verbs for a single path, cutting duplication.

app.route('/users')
  .get(function(req, res, next) {
    // handle GET /users
  })
  .post(function(req, res, next) {
    // handle POST /users
  });

All middleware attached to the chain runs only for /users, so you avoid repeating the path string in every verb.

How can I organize routes with the new express.Router?

The new express.Router works like a mini-app, so you can split each resource into its own file.

var express = require('express');
var people = express.Router();

people.use(function(req, res, next) {
  // router-level middleware
  next();
});

people.get('/', function(req, res) {
  res.send('People index');
});

module.exports = people;

Mount it in the main app with app.use('/people', require('./routes/people'));. This mirrors the way you'd structure a large Express 3 app but with a cleaner, dependency-free core.

Common Questions

Does removing bundled middleware break existing code?
It only breaks if you were relying on the implicit require; you must add the middleware as a separate npm dependency.

Which package replaces bodyParser after the upgrade?
Install the standalone body-parser module and use it like before.

Can I still use app.get() and app.post() as before?
Yes, the verb helpers work unchanged.

How do I mount a router on a sub-path?
Call app.use('/path', routerInstance) where routerInstance is created via express.Router().

What happens to code that still calls app.use(app.router)?
The call becomes a no-op and the router will be added twice, leading to duplicate handlers.

Releases In Branch 4

VersionRelease date
4.22.101 Dec 2025
(5 months ago)
4.0.009 Apr 2014
(12 years ago)