Express.js 5: Node’s Latest Web Framework Release

By Jon Church on Aug. 7th, 2020

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:

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.

Previous post:

The Nodejs.org community is redesigning the Nodejs.org website. The current website hasn’t had a major overhaul since 2014. Node.js, its place in the industry, and the community around it have grown quite a bit in that time. This project relies on volunteers to bring it to life, and you can get involved to help provide a better home for the Node.js community.

By Jon Church on Jul. 22nd, 2020
Next post:

We've started a new short video series on YouTube where we discuss learning Node.js with experienced developers. It's a very informal chat on Zoom that we just recorded on the fly. We've started off talking with Anna Mykhailova (@sunnyenotick), who is one of the experts who created some of the tutorials on HeyNode.com (the event loop section).

By Addison Berry on Jul. 26th, 2021