Express.js 5: Node’s Latest Web Framework Release
A new major version of Express.js is coming, the first major version bump since Express 4 was released in April of 2014. Although Express 5 is a major version change in the SemVer sense, the Node.js framework remains largely the same. Much of what's changed is centered around removing function signatures, which were deprecated in Express 4. You won't have to relearn much to continue to work with Express 5.
This version has been under development for a long time, and contains a lot of maintenance-related updates that could only be done in a major version (like breaking dependency updates, removing deprecated features, etc). One of the goals of 5 is to resolve overdue updates to allow for the possibility of bigger changes in the future.
That caveat aside, here are some of the notable changes coming to Express 5:
- Route Matching Changes
- Async Middleware/Route Handlers
- Default to Simple Query Parser Setting
- Remove Deprecated Features
- Community Updates
There isn't exactly an ETA on Express 5's release, but by the end of 2020 is a very safe estimate. However, you can try out the latest release by running npm i express@next
. You can also keep an eye on the tracking pull request for 5.
Route Matching Changes
Express 5's router upgraded to path-to-regexp@2.x
, which brings changes to path matching:
-
RegExp special characters can now only be used in a parameter, as opposed to anywhere.
-
No wildcard asterisk
*
-- use parameters instead ((.*)
or:splat*
) Migrating use of wildcards would look like the following:// v4 code app.get("*", (req, res) => {}); // Matches /, /foo, /foo/bar, etc app.get("/foo/*/baz", (req, res) => {}); // Matches /foo/bar/baz, /foo/qux/baz, etc // Equivalent v5 code app.get("(.*)", (req, res) => {}); app.get("/foo/(.*)/baz", (req, res) => {});
-
Explicit trailing slash
-
/foo/
will match only/foo/
and nothing else - For old behavior use
/foo
instead.
-
-
Parameters can have suffixes to augment meaning and affect how matching works:
-
*
: Zero or more, e.g./:foo*
matches/bar/baz/qux
and/
-
+
: One or more, e.g./:foo+
matches/bar
and/bar/baz
but not/
-
?
: Optional, e.g./:foo/:bar?
matches/baz
and/baz/qux
-
Async Middleware and Route Handlers
It was common under Express 4 for users to rely on packages such as express-async-handler
or create their own helper functions to catch rejections of handlers that returned promises. Express 5 will properly handle rejected promises returned from middleware functions and route handlers, passing the rejection on to your error handler.
Express 4 ignores the rejection of the Promise implicitly returned from this async function:
app.use(async (req, res, next) => {
throw new Error("BOOM!");
});
The above is equivalent to returning a Promise explicitly from a middleware or route handler:
app.use((req, res, next) => {
return new Promise((resolve, reject) => {
reject(new Error("BOOM"));
});
});
Express 5 will handle rejections from Promises returned from middleware or route handlers by passing the rejection as the first argument to next
.
This allows you to refactor code that looks like this:
function willThrow() {
throw new Error("BOOM");
}
// Express v4
router.get("/test", async (req, res, next) => {
try {
await willThrow();
res.send("okay");
} catch (err) {
next(err);
}
});
into this:
function willThrow() {
throw new Error("BOOM");
}
// Express v5
router.get("/test", async (req, res) => {
await willThrow();
res.send("okay");
});
Default to Simple Query Parser Setting
Query parsing will no longer use the extended
option by default. It will default to simple
. Extended query parsing allows you to use nested query parameters, e.g. /url?a[0]=b&a[1]=c
. It uses the qs
library for parsing.
To opt back in to extended query parsing:
app.set("query parser", "extended");
Simple query parsing instead uses Node.js' querystring
module, and does not support nesting parameters.
Remove Deprecated Features
There are a host of features which were marked as deprecated in Express 4; using them would print a deprecation warning to the console. Most have been deprecated for several years.
These deprecated features have been removed in Express 5. They are almost entirely outdated function signatures, e.g. res.json(status, body)
, which were superseded in the Express 4 line by res.status(status).json(body)
. You can see the entire list in the History file, where they're noted with remove
.
If your app doesn't currently print Express deprecation warnings, you shouldn't be affected by these changes.
Community Updates
Express became part of the OpenJS Foundation (OpenJSF) in 2019, joining projects such as Node.js, Electron, lodash, webpack, nvm, and many others. The OpenJSF has worked with Express to improve its governance and code of conduct, and generally provided support for the community of maintainers.
If you're interested in what’s happening in Express, you can follow along with the Technical Committee discussions and also catch up by watching recordings of past meetings.
For several years Express has been maintained by a small group of very dedicated volunteers, but in 2020 the Express contributor community has been growing. Part of that growth is a Triage team, started with the help of the Node.js Package Maintenance Working Group. The Package Maintenance WG aims to improve the lives of maintainers in the Node ecosystem. Express' triage initiative is a pilot project in partnership with the working group. Since kicking off in late 2019, it has seen a lot of success and offered new Express contributors a way to get involved.
The Triage team helps the maintainers manage issues and pull requests by reviewing, labeling, asking for more information, answering questions, and reproducing bugs. The goal is not just to relieve the maintainers of some repetitive work, but also to get more people up to speed to contribute to the packages that make up Express.
Packages like express
, multer
, and express-session
are not only downloaded millions of times a month, but are an entry point into the ecosystem for many new Node.js developers. That means the issue trackers see a lot of activity, thus creating work for maintainers and contribution opportunities for the Triage team.
Bringing on dedicated contributors is an important part of Express's long-term health. It can be difficult to start contributing to a project as large as Express, but the Triage team is an important new development for getting new people acclimated to the project. With more contributors who are committed to working on Express long term, we can hopefully see the next version released sooner than the 6 years it took for Express 5 to be completed!
If you're interested in joining the Triage team you can read the Triager Guide to see what it involves, and following these instructions to apply.