Express 5 is not very different from Express 4; although it maintains the same basic API, there are still changes that break compatibility with the previous version. Therefore, an application built with Express 4 might not work if you update it to use Express 5.
To install this version, you need to have a Node.js version 18 or higher. Then, execute the following command in your application directory:
$ npm install "express@^5.0.1"
You can then run your automated tests to see what fails, and fix problems according to the updates listed below. After addressing test failures, run your app to see what errors occur. You’ll find out right away if the app uses any methods or properties that are not supported.
Removed methods and properties
Changed
Improvements
If you use any of these methods or properties in your app, it will crash. So, you’ll need to change your app after you update to version 5.
Express 5 no longer supports the app.del()
function. If you use this function, an error is thrown. For registering HTTP DELETE routes, use the app.delete()
function instead.
Initially, del
was used instead of delete
, because delete
is a reserved keyword in JavaScript. However, as of ECMAScript 6, delete
and other reserved keywords can legally be used as property names.
The app.param(fn)
signature was used for modifying the behavior of the app.param(name, fn)
function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all.
The following method names have been pluralized. In Express 4, using the old methods resulted in a deprecation warning. Express 5 no longer supports them at all:
req.acceptsCharset()
is replaced by req.acceptsCharsets()
.
req.acceptsEncoding()
is replaced by req.acceptsEncodings()
.
req.acceptsLanguage()
is replaced by req.acceptsLanguages()
.
A leading colon character (:) in the name for the app.param(name, fn)
function is a remnant of Express 3, and for the sake of backwards compatibility, Express 4 supported it with a deprecation notice. Express 5 will silently ignore it and use the name parameter without prefixing it with a colon.
This should not affect your code if you follow the Express 4 documentation of app.param, as it makes no mention of the leading colon.
This potentially confusing and dangerous method of retrieving form data has been removed. You will now need to specifically look for the submitted parameter name in the req.params
, req.body
, or req.query
object.
Express 5 no longer supports the signature res.json(obj, status)
. Instead, set the status and then chain it to the res.json()
method like this: res.status(status).json(obj)
.
Express 5 no longer supports the signature res.jsonp(obj, status)
. Instead, set the status and then chain it to the res.jsonp()
method like this: res.status(status).jsonp(obj)
.
Express 5 no longer supports the signature res.redirect(url, status)
. Instead, use the following signature: res.redirect(status, url)
.
Express 5 no longer supports the magic string back
in the res.redirect()
and res.location()
methods. Instead, use the req.get('Referrer') || '/'
value to redirect back to the previous page. In Express 4, the res.redirect('back')
and res.location('back')
methods were deprecated.
Express 5 no longer supports the signature res.send(obj, status)
. Instead, set the status and then chain it to the res.send()
method like this: res.status(status).send(obj)
.
Express 5 no longer supports the signature res.send(status)
, where status
is a number. Instead, use the res.sendStatus(statusCode)
function, which sets the HTTP response header status code and sends the text version of the code: “Not Found”, “Internal Server Error”, and so on.
If you need to send a number by using the res.send()
function, quote the number to convert it to a string, so that Express does not interpret it as an attempt to use the unsupported old signature.
The res.sendfile()
function has been replaced by a camel-cased version res.sendFile()
in Express 5.
Path route matching syntax is when a string is supplied as the first parameter to the app.all()
, app.use()
, app.METHOD()
, router.all()
, router.METHOD()
, and router.use()
APIs. The following changes have been made to how the path string is matched to an incoming request:
*
must have a name, matching the behavior of parameters :
, use /*splat
instead of /*
?
is no longer supported, use braces instead: /:file{.:ext}
.app.get('/[discussion|page]/:slug', async (req, res) => {
res.status(200).send('ok')
})
should be changed to:
app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
res.status(200).send('ok')
})
()[]?+!
), use \
to escape them.:"this"
.Request middleware and handlers that return rejected promises are now handled by forwarding the rejected value as an Error
to the error handling middleware. This means that using async
functions as middleware and handlers are easier than ever. When an error is thrown in an async
function or a rejected promise is await
ed inside an async function, those errors will be passed to the error handler as if calling next(err)
.
Details of how Express handles errors is covered in the error handling documentation.
The express.urlencoded
method makes the extended
option false
by default.
In Express 5, the app.listen
method will invoke the user-provided callback function (if provided) when the server receives an error event. In Express 4, such errors would be thrown. This change shifts error-handling responsibility to the callback function in Express 5. If there is an error, it will be passed to the callback as an argument.
For example:
const server = app.listen(8080, '0.0.0.0', (error) => {
if (error) {
throw error // e.g. EADDRINUSE
}
console.log(`Listening on ${JSON.stringify(server.address())}`)
})
The app.router
object, which was removed in Express 4, has made a comeback in Express 5. In the new version, this object is a just a reference to the base Express router, unlike in Express 3, where an app had to explicitly load it.
The req.body
property returns undefined
when the body has not been parsed. In Express 4, it returns {}
by default.
In Express 4, the req.host
function incorrectly stripped off the port number if it was present. In Express 5, the port number is maintained.
The req.query
property is no longer a writable property and is instead a getter. The default query parser has been changed from “extended” to “simple”.
The res.clearCookie
method ignores the maxAge
and expires
options provided by the user.
The res.status
method only accepts integers in the range of 100
to 999
, following the behavior defined by Node.js, and it returns an error when the status code is not an integer.
The res.vary
throws an error when the field
argument is missing. In Express 4, if the argument was omitted, it gave a warning in the console
This method now enforces asynchronous behavior for all view engines, avoiding bugs caused by view engines that had a synchronous implementation and that violated the recommended interface.
Express 5 supports Brotli encoding for requests received from clients that support it.