Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: v5 release blog post #1616

Merged
merged 27 commits into from
Oct 15, 2024
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3c8ab5e
feat: v5 release
wesleytodd Sep 13, 2024
d2c022b
delete duplicated removal notices
jonchurch Oct 7, 2024
5481ac0
Update _posts/2024-09-12-v5-release.md
jonchurch Oct 7, 2024
26d16fc
Update _posts/2024-09-12-v5-release.md
jonchurch Oct 7, 2024
7bd3c54
typos, :name* change per blake
jonchurch Oct 7, 2024
397d300
General edits, some review feedback
crandmck Oct 9, 2024
0c430e7
Add a missing TO DO
crandmck Oct 9, 2024
9daa4c1
docs: removed ambiguous reference
UlisesGascon Oct 9, 2024
5759126
docs: Removed TODO
UlisesGascon Oct 9, 2024
1712f98
docs: linting
UlisesGascon Oct 9, 2024
3e74ca8
docs: added sponsorship link
UlisesGascon Oct 9, 2024
f63fb37
docs: added links to CVE-2024-45590, security triage team and last bl…
UlisesGascon Oct 9, 2024
0757b4b
docs: improved metadata
UlisesGascon Oct 9, 2024
eea1255
docs: added explanation in the deprecated APIs
UlisesGascon Oct 9, 2024
3e0f923
docs: added section for Migration and Security Guidance
UlisesGascon Oct 9, 2024
88dcaef
Final polish, add toc links to breaking change sections
crandmck Oct 11, 2024
d9fbc6e
Change xref to migration guide from changelog
crandmck Oct 12, 2024
5b1b2a0
Update _posts/2024-09-12-v5-release.md
UlisesGascon Oct 15, 2024
1cd04c1
Update _posts/2024-09-12-v5-release.md
UlisesGascon Oct 15, 2024
7c2104c
Update _posts/2024-09-12-v5-release.md
UlisesGascon Oct 15, 2024
c31e217
Update _posts/2024-09-12-v5-release.md
UlisesGascon Oct 15, 2024
eacff0c
Update _posts/2024-09-12-v5-release.md
UlisesGascon Oct 15, 2024
7cd9b15
Update _posts/2024-09-12-v5-release.md
UlisesGascon Oct 15, 2024
87408ca
Update _posts/2024-09-12-v5-release.md
UlisesGascon Oct 15, 2024
ae42d70
Update _posts/2024-09-12-v5-release.md
UlisesGascon Oct 15, 2024
cf462b6
Update _posts/2024-09-12-v5-release.md
UlisesGascon Oct 15, 2024
146185b
Move file to change post date
crandmck Oct 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions _posts/2024-10-15-v5-release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
---
title: "Introducing Express v5: A New Era for Node.js Framework"
tags: releases
author: Wes Todd and the Express Technical Committee
description: Announcing the release of Express version 5
---

Ten years ago (July 2014) the [Express v5 release pull request](https://github.com/expressjs/express/pull/2237) was opened, and now at long last it's been merged and published!

We want to recognize the work of all our contributors, especially [Doug Wilson](https://github.com/dougwilson), who spent the last ten years ensuring Express was the most stable project around. Without his contributions and those of many others, this release could not have happened.

Eight months ago we went public with a plan to move [Express forward](https://github.com/expressjs/discussions/issues/160). This plan included re-committing to the governance outlined years ago and adding more contributors to help kickstart progress. Many people may not realize that robust project governance is critical to the health of a large open-source project. We want to thank the [OpenJS Foundation Cross Project
Council](https://github.com/openjs-foundation/cross-project-council/) and its members for helping us put together this plan.

## So what about v5?

This release is designed to be boring!
That may sound odd, but we've intentionally kept it simple to unblock the ecosystem and enable more impactful changes in future releases. This is also about signaling to the Node.js ecosystem that Express is moving again.
The focus of this release is on dropping old Node.js version support, addressing security concerns, and simplifying maintenance.

Before going into the changes in this release, let's address why it was released v5 on the `next` dist-tag. As part of reviving the project, we started a [Security working group](https://github.com/expressjs/security-wg) and [security triage team](https://github.com/expressjs/security-wg?tab=readme-ov-file#security-triage-team) to address the growing needs around open source supply chain security. We undertook a security audit (more details to come on that) and uncovered some problems that needed to be addressed. Thus, in addition to the "normal" work done in public issues, we also did a lot of security work in private forks.
This security work required orchestration when releasing, to ensure the code and CVE reports went out together. You can find a summary of the most recent vulnerabilities patched in [our security release notes](https://expressjs.com/2024/09/29/security-releases.html).

While we weren't able to simultaneously release v5, this blog post, the changelog, and documentation, we felt it was most important to have a secure and stable release.

As soon as possible, we'll provide more details on our long-term support (LTS) plans, including when the release will move from `next` to `latest`. For now, if you are uncomfortable being on the bleeding edge (even if it is a rather dull edge) then you should wait to upgrade until the release is tagged `latest`. That said, we look forward to working with you to address any bugs you encounter as you upgrade.

## Breaking changes

The v5 release has the minimum possible number of breaking changes, listed here in order of impact to applications.

- [Ending support for old Node.js versions](#goodbye-nodejs-010-hello-node-18)
- [Changes to path matching and regular expressions](#changes-to-path-matching-and-regular-expressions)
- [Promise support](#promise-support)
- [Body parser changes](#body-parser-changes)
- [Removing deprecated method signatures](#removing-deprecated-method-signatures)

There are also a number of subtle changes: for details, see [Migrating to Express 5]({{site.url}}/{{page.lang}}/guide/migrating-5).

### Ending support for old Node.js versions

Goodbye Node.js 0.10, hello Node 18 and up!

This release drops support for Node.js versions before v18. This is an important change because supporting old Node.js versions has been holding back many critical performance and maintainability changes. This change also enables more stable and maintainable continuous integration (CI), adopting new language and runtime features, and dropping dependencies that are no longer required.

We recognize that this might cause difficulty for some enterprises with older or "parked" applications, and because of this we are working on a [partnership with HeroDevs](https://expressjs.com/2024/10/01/HeroDevs-partnership-announcement.html) to offer "never-ending support" that will include critical security patches even after v4 enters end-of-life (more on these plans soon). That said, we strongly suggest that you update to modern Node.js versions as soon as possible.

### Changes to path matching and regular expressions

The v5 releases updates to `path-to-regexp@8.x` from `path-to-regexp@0.x`, which incorporates many years of changes. If you were using any of the 5.0.0-beta releases, a last-minute update which greatly changed the path semantics to [remove the possibility of any ReDoS attacks](https://blakeembrey.com/posts/2024-09-web-redos/). For more detailed changes, [see the `path-to-regexp` readme](https://github.com/pillarjs/path-to-regexp?tab=readme-ov-file#express--4x).

#### No more regex

This release no longer supports "sub-expression" regular expressions, for example `/:foo(\\d+)`.
This is a commonly-used pattern, but we removed it for security reasons. Unfortunately, it's easy to write a regular expression that has exponential time behavior when parsing input: The dreaded regular expression denial of service (ReDoS) attack. It's very difficult to prevent this, but as a library that converts strings to regular expressions, we are on the hook for such security aspects.

*How to migrate:* The best approach to prevent ReDoS attacks is to use a robust input validation library. [There are many on `npm`](https://www.npmjs.com/search?q=validate%20express) depending on your needs. TC member Wes Todd maintains [a middleware-based "code first" OpenAPI library](https://www.npmjs.com/package/@wesleytodd/openapi) for this kind of thing.

#### Splats, optional, and captures oh my

This release includes simplified patterns for common route patterns. With the removal of regular expression semantics comes other small but impactful changes to how you write your routes.

1. `:name?` becomes `{:name}`. Usage of `{}` for optional parts of your route means you can now do things like `/base{/:optional}/:required` and what parts are actually optional is much more explicit.
2. `*` becomes `*name`.
3. New reserved characters: `(`, `)`, `[`, `]`, `?`, `+`, & `!`. These have been reserved to leave room for future improvements and to prevent mistakes when migrating where those characters mean specific things in previous versions.

#### Name everything

This release no longer supports ordered numerical parameters.

In Express v4, you could get numerical parameters using regex capture groups (for example, `/user(s?)` => `req.params[0] === 's'`). Now all parameters must be named. Along with requiring a name, Express now supports all valid JavaScript identifiers or quoted (for example, `/:"this"`).

### Promise support

This one may be a bit contentious, but we "promise" we're moving in the right direction. We added support for returned *rejected* promises from errors raised in middleware. This *does not include* calling `next` from returned *resolved* promises. There are a lot of edge cases in old Express apps that have expectations of `Promise` behavior, and before we can run we need to walk. For most folks, this means you can now write middleware like the following:

```javascript
app.use(async (req, res, next) => {
req.locals.user = await getUser(req);
next();
});
```

Notice that this example uses `async/await` and the `getUser` call may throw an error (if, for example, the user doesn't exist, the user database is down, and so on), but we still call `next` if it is successful. We don't need to catch the error in line anymore if we want to rely on error-handling middleware instead because the router will now catch the rejected promise and treat that as calling `next(err)`.

NOTE: Best practice is to handle errors as close to the site as possible. So while this is now handled in the router, it's best to catch the error in the middleware and handle it without relying on separate error-handling middleware.

### Body parser changes

There are a number of `body-parser` changes:

- Add option to customize the urlencoded body depth with a default value of 32 as mitigation for [CVE-2024-45590](https://nvd.nist.gov/vuln/detail/CVE-2024-45590) ([technical details](https://github.com/expressjs/body-parser/commit/b2695c4450f06ba3b0ccf48d872a229bb41c9bce))
- Remove deprecated `bodyParser()` combination middleware
- `req.body` is no longer always initialized to `{}`
- `urlencoded` parser now defaults `extended` to false
- Added support for Brotli lossless data compression

### Removing deprecated method signatures

Express v5 removes a number of deprecated method signatures, many of which were carried over from v3. Below are the changes you need to make:

- `res.redirect('back')` and `res.location('back')`: The magic string `'back'` is no longer supported. Use `req.get('Referrer') || '/'` explicitly instead.
- `res.send(status, body)` and `res.send(body, status)` signatures: Use `res.status(status).send(body)`.
- `res.send(status)` signature: Use `res.sendStatus(status)` for simple status responses, or `res.status(status).send()` for sending a status code with an optional body.
- `res.redirect(url, status)` signature: Use `res.redirect(status, url)`.
- `res.json(status, obj)` and `res.json(obj, status)` signatures: Use `res.status(status).json(obj)`.
- `res.jsonp(status, obj)` and `res.jsonp(obj, status)` signatures: Use `res.status(status).jsonp(obj)`.
- `app.param(fn)`: This method has been deprecated. Instead, access parameters directly via `req.params`, or use `req.body` or `req.query` as needed.
- `app.del('/', () => {})` method: Use `app.delete('/', () => {})` instead.
- `req.acceptsCharset`: Use `req.acceptsCharsets` (plural).
- `req.acceptsEncoding`: Use `req.acceptsEncodings` (plural).
- `req.acceptsLanguage`: Use `req.acceptsLanguages` (plural).
- `res.sendfile` method: Use `res.sendFile` instead.

As a framework, we aim to ensure that the API is as consistent as possible. We've removed these deprecated signatures to make the API more predictable and easier to use. By streamlining each method to use a single, consistent signature, we simplify the developer experience and reduce confusion.

## Migration and security guidance

For developers looking to migrate from v4 to v5, there's a [detailed migration guide]({{site.url}}/{{page.lang}}/guide/migrating-5) to help you navigate through the changes and ensure a smooth upgrade process.

Additionally, we’ve been working hard on a comprehensive [Threat Model](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) that helps illustrate our philosophy of a "Fast, unopinionated, minimalist web framework for Node.js." It provides critical insights into areas like user input validation and security practices that are essential for safe and secure usage of Express in your applications.

## Our work is just starting

We see the v5 release as a milestone toward an Express ecosystem that's a stable and reliable tool for companies, governments, educators, and hobby projects. It is our commitment as the new stewards of the Express project to move the ecosystem forward with this goal in mind. If you want to support this work, which we do on a volunteer basis, please consider supporting the project and its maintainers via [our sponsorship opportunities](https://opencollective.com/express).

We have an [extensive working backlog](https://github.com/expressjs/discussions/issues/266) of tasks, PRs, and issues for Express and dependencies. Naturally, we expect developers will continue to report issues to add to this backlog and open PRs moving forward, and we'll continue to collaborate with the community to triage and resolve them. We look forward to continuing to improve Express and making it useful for its users across the world.
Loading