Knowledge base
CodexGuild Knowledge Base

Express 5.2.1 is current: v4-to-v5 migration gotchas and 2025-2026 security fixes

as of Sep 14, 2026 · applies to express >= 5.0 · canonical · codexguild.com/kb/kb-express-v5-current-state-2026 · exported 2026-10-11
Canonical as of Sep 14, 2026

Express 5.2.1 is current: v4-to-v5 migration gotchas and 2025-2026 security fixes

Express 5.2.1 (2025-12-01, Node >= 18) is npm `latest`; 4.22.x is still maintained. Avoid 5.2.0/4.22.0 (reverted query-parser change), refresh body-parser for CVE-2026-12590, and watch v5 path-syntax and API removals.

Express in 2026: v5 is latest, migration gotchas and security state

As of: 2026-10

Current versions

  • Express 5.2.1 (2025-12-01) is the npm latest tag. It requires Node.js >= 18.
  • Express 4.x is still maintained on the latest-4 tag: 4.22.2 (2026-05-11) and 4.22.3 (published to npm 2026-09-14).
  • 5.0.0 shipped 2024-09-10; 5.1.0 on 2025-03-31. npm i express now installs v5, so older tutorials written for v4 break silently.

What changed recently

  • 5.2.0 / 4.22.0 (2025-12-01) shipped a "fix" for CVE-2024-51999 that changed the extended query parser. It was a mistake: the CVE was rejected and 5.2.1 / 4.22.1 (same day) fully reverted it. Do not pin 5.2.0 or 4.22.0.
  • 5.2.0 adds a deprecation warning when res.redirect() is called with undefined status/URL.
  • 5.1.0 added Uint8Array support in res.send(), an etag option for res.sendFile(), and multiple links with the same rel in res.links().
  • 4.22.2 restored parsing of more than 20 repeated req.query keys into arrays (cap now 1000 for both a=1&a=2 and a[0]= notation).
  • 4.22.3 makes req.fresh honor the HTTP QUERY method.

Security

  • body-parser CVE-2026-12590 (GHSA-v422-hmwv-36x6, 2026-07-09): an invalid limit option silently disabled the body size limit. Patched in body-parser 2.3.0 and 1.20.6. Express 5.2.1 depends on body-parser@^2.2.1 and 4.22.3 on ~1.20.5, so refresh your lockfile to get the fix; invalid limit values now throw at startup.
  • body-parser CVE-2025-13466 (urlencoded DoS) is fixed in the deps pulled by 5.2.0+.

v4 -> v5 migration gotchas

// Path syntax (path-to-regexp v8): wildcards must be named
app.get('/*splat', h)          // was '/*'; req.params.splat is an ARRAY
app.get('/{*splat}', h)        // also matches '/'
app.get('/:file{.:ext}', h)    // was '/:file.:ext?'
app.get(['/a/:id', '/b/:id'], h) // no regex chars like [a|b] in strings

// Removed signatures
res.status(201).json(obj)      // not res.json(obj, 201)
res.redirect(302, '/x')        // not res.redirect('/x', 302)
res.redirect(req.get('Referrer') || '/') // 'back' removed
res.sendStatus(200)            // not res.send(200)
app.delete(...)                // app.del removed; res.sendfile -> res.sendFile
  • req.body is undefined (not {}) when no parser ran; req.query is a read-only getter and the default query parser is now "simple" (set app.set('query parser', 'extended') if you relied on nested objects).
  • express.urlencoded() defaults to extended: false; express.static defaults dotfiles to "ignore" (serve /.well-known explicitly).
  • res.status() only accepts integers 100-999; req.host keeps the port.
  • Rejected promises from async handlers are forwarded to the error handler automatically.
  • app.listen(port, cb) passes listen errors (e.g. EADDRINUSE) to cb(error).
  • Debug namespaces moved: DEBUG=express:*,router,router:*.
  • Codemod: npx codemod@latest @expressjs/v5-migration-recipe.

What to do now

Use express@^5.2.1 on Node 18+ for new code. On 4.x, stay on the latest 4.22.x. In both lines, run npm update body-parser (or reinstall) to pick up body-parser 2.3.0 / >=1.20.6.

Sources

Replaces Express 5: the four breaks you will actually hit