# Express > title: Express 3.x - API Reference --- --- layout: api version: 3x title: Express 3.x - API Reference description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods. menu: api redirect_from: "/3x/api.html" ---
**Express 3.x IS END-OF-LIFE AND NO LONGER MAINTAINED** Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express. If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options).

3.x API

{% include api/en/3x/express.md %} {% include api/en/3x/app.md %} {% include api/en/3x/req.md %} {% include api/en/3x/res.md %} {% include api/en/3x/middleware.md %}
--- --- layout: api version: 4x title: Express 4.x - API Reference description: Access the API reference for Express.js 4.x, detailing all modules, methods, and properties for building web applications with this version. menu: api redirect_from: "/4x/api.html" ---

4.x API

{% capture node-version %} Express 4.0 requires Node.js 0.10 or higher. {% endcapture %} {% include admonitions/note.html content=node-version %} {% include api/en/4x/express.md %} {% include api/en/4x/app.md %} {% include api/en/4x/req.md %} {% include api/en/4x/res.md %} {% include api/en/4x/router.md %}
--- --- layout: api version: 5x title: Express 5.x - API Reference description: Access the API reference for Express.js 5.x, detailing all modules, methods, and properties for building web applications with this latest version. menu: api redirect_from: "/5x/api.html" ---

5.x API

{% capture node-version %} Express 5.0 requires Node.js 18 or higher. {% endcapture %} {% include admonitions/note.html content=node-version %} {% include api/en/5x/express.md %} {% include api/en/5x/app.md %} {% include api/en/5x/req.md %} {% include api/en/5x/res.md %} {% include api/en/5x/router.md %}
--- --- layout: page title: Performance Best Practices Using Express in Production description: Discover performance and reliability best practices for Express apps in production, covering code optimizations and environment setups for optimal performance. menu: advanced order: 4 redirect_from: "/advanced/best-practice-performance.html" --- # Production best practices: performance and reliability This article discusses performance and reliability best practices for Express applications deployed to production. This topic clearly falls into the "devops" world, spanning both traditional development and operations. Accordingly, the information is divided into two parts: * Things to do in your code (the dev part): * [Use gzip compression](#use-gzip-compression) * [Don't use synchronous functions](#dont-use-synchronous-functions) * [Do logging correctly](#do-logging-correctly) * [Handle exceptions properly](#handle-exceptions-properly) * Things to do in your environment / setup (the ops part): * [Set NODE_ENV to "production"](#set-node_env-to-production) * [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) * [Run your app in a cluster](#run-your-app-in-a-cluster) * [Cache request results](#cache-request-results) * [Use a load balancer](#use-a-load-balancer) * [Use a reverse proxy](#use-a-reverse-proxy) ## Things to do in your code {#in-code} Here are some things you can do in your code to improve your application's performance: * [Use gzip compression](#use-gzip-compression) * [Don't use synchronous functions](#dont-use-synchronous-functions) * [Do logging correctly](#do-logging-correctly) * [Handle exceptions properly](#handle-exceptions-properly) ### Use gzip compression Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://www.npmjs.com/package/compression) middleware for gzip compression in your Express app. For example: ```js const compression = require('compression') const express = require('express') const app = express() app.use(compression()) ``` For a high-traffic website in production, the best way to put compression in place is to implement it at a reverse proxy level (see [Use a reverse proxy](#use-a-reverse-proxy)). In that case, you do not need to use compression middleware. For details on enabling gzip compression in Nginx, see [Module ngx_http_gzip_module](http://nginx.org/en/docs/http/ngx_http_gzip_module.html) in the Nginx documentation. ### Don't use synchronous functions Synchronous functions and methods tie up the executing process until they return. A single call to a synchronous function might return in a few microseconds or milliseconds, however in high-traffic websites, these calls add up and reduce the performance of the app. Avoid their use in production. Although Node and many modules provide synchronous and asynchronous versions of their functions, always use the asynchronous version in production. The only time when a synchronous function can be justified is upon initial startup. You can use the `--trace-sync-io` command-line flag to print a warning and a stack trace whenever your application uses a synchronous API. Of course, you wouldn't want to use this in production, but rather to ensure that your code is ready for production. See the [node command-line options documentation](https://nodejs.org/api/cli.html#cli_trace_sync_io) for more information. ### Do logging correctly In general, there are two reasons for logging from your app: For debugging and for logging app activity (essentially, everything else). Using `console.log()` or `console.error()` to print log messages to the terminal is common practice in development. But [these functions are synchronous](https://nodejs.org/api/console.html#console) when the destination is a terminal or a file, so they are not suitable for production, unless you pipe the output to another program. #### For debugging If you're logging for purposes of debugging, then instead of using `console.log()`, use a special debugging module like [debug](https://www.npmjs.com/package/debug). This module enables you to use the DEBUG environment variable to control what debug messages are sent to `console.error()`, if any. To keep your app purely asynchronous, you'd still want to pipe `console.error()` to another program. But then, you're not really going to debug in production, are you? #### For app activity If you're logging app activity (for example, tracking traffic or API calls), instead of using `console.log()`, use a logging library like [Pino](https://www.npmjs.com/package/pino), which is the fastest and most efficient option available. ### Handle exceptions properly Node apps crash when they encounter an uncaught exception. Not handling exceptions and taking appropriate actions will make your Express app crash and go offline. If you follow the advice in [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) below, then your app will recover from a crash. Fortunately, Express apps typically have a short startup time. Nevertheless, you want to avoid crashing in the first place, and to do that, you need to handle exceptions properly. To ensure you handle all exceptions, use the following techniques: * [Use try-catch](#use-try-catch) * [Use promises](#use-promises) Before diving into these topics, you should have a basic understanding of Node/Express error handling: using error-first callbacks, and propagating errors in middleware. Node uses an "error-first callback" convention for returning errors from asynchronous functions, where the first parameter to the callback function is the error object, followed by result data in succeeding parameters. To indicate no error, pass null as the first parameter. The callback function must correspondingly follow the error-first callback convention to meaningfully handle the error. And in Express, the best practice is to use the next() function to propagate errors through the middleware chain. For more on the fundamentals of error handling, see: * [Error Handling in Node.js](https://www.tritondatacenter.com/node-js/production/design/errors) #### Use try-catch Try-catch is a JavaScript language construct that you can use to catch exceptions in synchronous code. Use try-catch, for example, to handle JSON parsing errors as shown below. Here is an example of using try-catch to handle a potential process-crashing exception. This middleware function accepts a query field parameter named "params" that is a JSON object. ```js app.get('/search', (req, res) => { // Simulating async operation setImmediate(() => { const jsonStr = req.query.params try { const jsonObj = JSON.parse(jsonStr) res.send('Success') } catch (e) { res.status(400).send('Invalid JSON string') } }) }) ``` However, try-catch works only for synchronous code. Because the Node platform is primarily asynchronous (particularly in a production environment), try-catch won't catch a lot of exceptions. #### Use promises When an error is thrown in an `async` function or a rejected promise is awaited inside an `async` function, those errors will be passed to the error handler as if calling `next(err)` ```js app.get('/', async (req, res, next) => { const data = await userData() // If this promise fails, it will automatically call `next(err)` to handle the error. res.send(data) }) app.use((err, req, res, next) => { res.status(err.status ?? 500).send({ error: err.message }) }) ``` Also, you can use asynchronous functions for your middleware, and the router will handle errors if the promise fails, for example: ```js app.use(async (req, res, next) => { req.locals.user = await getUser(req) next() // This will be called if the promise does not throw an error. }) ``` 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. #### What not to do One thing you should _not_ do is to listen for the `uncaughtException` event, emitted when an exception bubbles all the way back to the event loop. Adding an event listener for `uncaughtException` will change the default behavior of the process that is encountering an exception; the process will continue to run despite the exception. This might sound like a good way of preventing your app from crashing, but continuing to run the app after an uncaught exception is a dangerous practice and is not recommended, because the state of the process becomes unreliable and unpredictable. Additionally, using `uncaughtException` is officially recognized as [crude](https://nodejs.org/api/process.html#process_event_uncaughtexception). So listening for `uncaughtException` is just a bad idea. This is why we recommend things like multiple processes and supervisors: crashing and restarting is often the most reliable way to recover from an error. We also don't recommend using [domains](https://nodejs.org/api/domain.html). It generally doesn't solve the problem and is a deprecated module. ## Things to do in your environment / setup {#in-environment} Here are some things you can do in your system environment to improve your app's performance: * [Set NODE_ENV to "production"](#set-node_env-to-production) * [Ensure your app automatically restarts](#ensure-your-app-automatically-restarts) * [Run your app in a cluster](#run-your-app-in-a-cluster) * [Cache request results](#cache-request-results) * [Use a load balancer](#use-a-load-balancer) * [Use a reverse proxy](#use-a-reverse-proxy) ### Set NODE_ENV to "production" The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set NODE_ENV to `production`. Setting NODE_ENV to "production" makes Express: * Cache view templates. * Cache CSS files generated from CSS extensions. * Generate less verbose error messages. [Tests indicate](https://www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/) that just doing this can improve app performance by a factor of three! If you need to write environment-specific code, you can check the value of NODE_ENV with `process.env.NODE_ENV`. Be aware that checking the value of any environment variable incurs a performance penalty, and so should be done sparingly. In development, you typically set environment variables in your interactive shell, for example by using `export` or your `.bash_profile` file. But in general, you shouldn't do that on a production server; instead, use your OS's init system (systemd). The next section provides more details about using your init system in general, but setting `NODE_ENV` is so important for performance (and easy to do), that it's highlighted here. With systemd, use the `Environment` directive in your unit file. For example: ```sh # /etc/systemd/system/myservice.service Environment=NODE_ENV=production ``` For more information, see [Using Environment Variables In systemd Units](https://www.flatcar.org/docs/latest/setup/systemd/environment-variables/). ### Ensure your app automatically restarts In production, you don't want your application to be offline, ever. This means you need to make sure it restarts both if the app crashes and if the server itself crashes. Although you hope that neither of those events occurs, realistically you must account for both eventualities by: * Using a process manager to restart the app (and Node) when it crashes. * Using the init system provided by your OS to restart the process manager when the OS crashes. It's also possible to use the init system without a process manager. Node applications crash if they encounter an uncaught exception. The foremost thing you need to do is to ensure your app is well-tested and handles all exceptions (see [handle exceptions properly](#handle-exceptions-properly) for details). But as a fail-safe, put a mechanism in place to ensure that if and when your app crashes, it will automatically restart. #### Use a process manager In development, you started your app simply from the command line with `node server.js` or something similar. But doing this in production is a recipe for disaster. If the app crashes, it will be offline until you restart it. To ensure your app restarts if it crashes, use a process manager. A process manager is a "container" for applications that facilitates deployment, provides high availability, and enables you to manage the application at runtime. In addition to restarting your app when it crashes, a process manager can enable you to: * Gain insights into runtime performance and resource consumption. * Modify settings dynamically to improve performance. * Control clustering (pm2). Historically, it was popular to use a Node.js process manager like [PM2](https://github.com/Unitech/pm2). See their documentation if you wish to do this. However, we recommend using your init system for process management. #### Use an init system The next layer of reliability is to ensure that your app restarts when the server restarts. Systems can still go down for a variety of reasons. To ensure that your app restarts if the server crashes, use the init system built into your OS. The main init system in use today is [systemd](https://wiki.debian.org/systemd). There are two ways to use init systems with your Express app: * Run your app in a process manager, and install the process manager as a service with the init system. The process manager will restart your app when the app crashes, and the init system will restart the process manager when the OS restarts. This is the recommended approach. * Run your app (and Node) directly with the init system. This is somewhat simpler, but you don't get the additional advantages of using a process manager. ##### Systemd Systemd is a Linux system and service manager. Most major Linux distributions have adopted systemd as their default init system. A systemd service configuration file is called a _unit file_, with a filename ending in `.service`. Here's an example unit file to manage a Node app directly. Replace the values enclosed in `` for your system and app: ```sh [Unit] Description= [Service] Type=simple ExecStart=/usr/local/bin/node WorkingDirectory= User=nobody Group=nogroup # Environment variables: Environment=NODE_ENV=production # Allow many incoming connections LimitNOFILE=infinity # Allow core dumps for debugging LimitCORE=infinity StandardInput=null StandardOutput=syslog StandardError=syslog Restart=always [Install] WantedBy=multi-user.target ``` For more information on systemd, see the [systemd reference (man page)](http://www.freedesktop.org/software/systemd/man/systemd.unit.html). ### Run your app in a cluster In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. ![Balancing between application instances using the cluster API](/images/clustering.png) IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](http://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers. In clustered apps, worker processes can crash individually without affecting the rest of the processes. Apart from performance advantages, failure isolation is another reason to run a cluster of app processes. Whenever a worker process crashes, always make sure to log the event and spawn a new process using cluster.fork(). #### Using Node's cluster module Clustering is made possible with Node's [cluster module](https://nodejs.org/api/cluster.html). This enables a master process to spawn worker processes and distribute incoming connections among the workers. #### Using PM2 If you deploy your application with PM2, then you can take advantage of clustering _without_ modifying your application code. You should ensure your [application is stateless](https://pm2.keymetrics.io/docs/usage/specifics/#stateless-apps) first, meaning no local data is stored in the process (such as sessions, websocket connections and the like). When running an application with PM2, you can enable **cluster mode** to run it in a cluster with a number of instances of your choosing, such as the matching the number of available CPUs on the machine. You can manually change the number of processes in the cluster using the `pm2` command line tool without stopping the app. To enable cluster mode, start your application like so: ```bash # Start 4 worker processes $ pm2 start npm --name my-app -i 4 -- start # Auto-detect number of available CPUs and start that many worker processes $ pm2 start npm --name my-app -i max -- start ``` This can also be configured within a PM2 process file (`ecosystem.config.js` or similar) by setting `exec_mode` to `cluster` and `instances` to the number of workers to start. Once running, the application can be scaled like so: ```bash # Add 3 more workers $ pm2 scale my-app +3 # Scale to a specific number of workers $ pm2 scale my-app 2 ``` For more information on clustering with PM2, see [Cluster Mode](https://pm2.keymetrics.io/docs/usage/cluster-mode/) in the PM2 documentation. ### Cache request results Another strategy to improve the performance in production is to cache the result of requests, so that your app does not repeat the operation to serve the same request repeatedly. Use a caching server like [Varnish](https://www.varnish-cache.org/) or [Nginx](https://blog.nginx.org/blog/nginx-caching-guide) (see also [Nginx Caching](https://serversforhackers.com/nginx-caching/)) to greatly improve the speed and performance of your app. ### Use a load balancer No matter how optimized an app is, a single instance can handle only a limited amount of load and traffic. One way to scale an app is to run multiple instances of it and distribute the traffic via a load balancer. Setting up a load balancer can improve your app's performance and speed, and enable it to scale more than is possible with a single instance. A load balancer is usually a reverse proxy that orchestrates traffic to and from multiple application instances and servers. You can easily set up a load balancer for your app by using [Nginx](https://nginx.org/en/docs/http/load_balancing.html) or [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts). With load balancing, you might have to ensure that requests that are associated with a particular session ID connect to the process that originated them. This is known as _session affinity_, or _sticky sessions_, and may be addressed by the suggestion above to use a data store such as Redis for session data (depending on your application). For a discussion, see [Using multiple nodes](https://socket.io/docs/v4/using-multiple-nodes/). ### Use a reverse proxy A reverse proxy sits in front of a web app and performs supporting operations on the requests, apart from directing requests to the app. It can handle error pages, compression, caching, serving files, and load balancing among other things. Handing over tasks that do not require knowledge of application state to a reverse proxy frees up Express to perform specialized application tasks. For this reason, it is recommended to run Express behind a reverse proxy like [Nginx](https://www.nginx.org/) or [HAProxy](https://www.haproxy.org/) in production. --- --- layout: page title: Security Best Practices for Express in Production description: Discover crucial security best practices for Express apps in production, including using TLS, input validation, secure cookies, and preventing vulnerabilities. menu: advanced order: 3 redirect_from: "/advanced/best-practice-security.html" --- # Production Best Practices: Security ## Overview The term _"production"_ refers to the stage in the software lifecycle when an application or API is generally available to its end-users or consumers. In contrast, in the _"development"_ stage, you're still actively writing and testing code, and the application is not open to external access. The corresponding system environments are known as _production_ and _development_ environments, respectively. Development and production environments are usually set up differently and have vastly different requirements. What's fine in development may not be acceptable in production. For example, in a development environment you may want verbose logging of errors for debugging, while the same behavior can become a security concern in a production environment. And in development, you don't need to worry about scalability, reliability, and performance, while those concerns become critical in production. {% capture security-note %} If you believe you have discovered a security vulnerability in Express, please see [Security Policies and Procedures](/en/resources/contributing.html#security-policies-and-procedures). {% endcapture %} {% include admonitions/note.html content=security-note %} Security best practices for Express applications in production include: - [Production Best Practices: Security](#production-best-practices-security) - [Overview](#overview) - [Don't use deprecated or vulnerable versions of Express](#dont-use-deprecated-or-vulnerable-versions-of-express) - [Use TLS](#use-tls) - [Do not trust user input](#do-not-trust-user-input) - [Prevent open redirects](#prevent-open-redirects) - [Use Helmet](#use-helmet) - [Reduce fingerprinting](#reduce-fingerprinting) - [Use cookies securely](#use-cookies-securely) - [Don't use the default session cookie name](#dont-use-the-default-session-cookie-name) - [Set cookie security options](#set-cookie-security-options) - [Prevent brute-force attacks against authorization](#prevent-brute-force-attacks-against-authorization) - [Ensure your dependencies are secure](#ensure-your-dependencies-are-secure) - [Avoid other known vulnerabilities](#avoid-other-known-vulnerabilities) - [Additional considerations](#additional-considerations) ## Don't use deprecated or vulnerable versions of Express Express 2.x and 3.x are no longer maintained. Security and performance issues in these versions won't be fixed. Do not use them! If you haven't moved to version 4, follow the [migration guide](/{{ page.lang }}/guide/migrating-4.html) or consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options). Also ensure you are not using any of the vulnerable Express versions listed on the [Security updates page](/{{ page.lang }}/advanced/security-updates.html). If you are, update to one of the stable releases, preferably the latest. ## Use TLS If your app deals with or transmits sensitive data, use [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS) to secure the connection and the data. This technology encrypts data before it is sent from the client to the server, thus preventing some common (and easy) hacks. Although Ajax and POST requests might not be visibly obvious and seem "hidden" in browsers, their network traffic is vulnerable to [packet sniffing](https://en.wikipedia.org/wiki/Packet_analyzer) and [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). You may be familiar with Secure Socket Layer (SSL) encryption. [TLS is simply the next progression of SSL](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx). In other words, if you were using SSL before, consider upgrading to TLS. In general, we recommend Nginx to handle TLS. For a good reference to configure TLS on Nginx (and other servers), see [Recommended Server Configurations (Mozilla Wiki)](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations). Also, a handy tool to get a free TLS certificate is [Let's Encrypt](https://letsencrypt.org/about/), a free, automated, and open certificate authority (CA) provided by the [Internet Security Research Group (ISRG)](https://www.abetterinternet.org/). ## Do not trust user input For web applications, one of the most critical security requirements is proper user input validation and handling. This comes in many forms and we will not cover all of them here. Ultimately, the responsibility for validating and correctly handling the types of user input your application accepts is yours. ### Prevent open redirects An example of potentially dangerous user input is an _open redirect_, where an application accepts a URL as user input (often in the URL query, for example `?url=https://example.com`) and uses `res.redirect` to set the `location` header and return a 3xx status. An application must validate that it supports redirecting to the incoming URL to avoid sending users to malicious links such as phishing websites, among other risks. Here is an example of checking URLs before using `res.redirect` or `res.location`: ```js app.use((req, res) => { try { if (new Url(req.query.url).host !== 'example.com') { return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`) } } catch (e) { return res.status(400).end(`Invalid url: ${req.query.url}`) } res.redirect(req.query.url) }) ``` ## Use Helmet [Helmet][helmet] can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. Helmet is a middleware function that sets security-related HTTP response headers. Helmet sets the following headers by default: - `Content-Security-Policy`: A powerful allow-list of what can happen on your page which mitigates many attacks - `Cross-Origin-Opener-Policy`: Helps process-isolate your page - `Cross-Origin-Resource-Policy`: Blocks others from loading your resources cross-origin - `Origin-Agent-Cluster`: Changes process isolation to be origin-based - `Referrer-Policy`: Controls the [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header - `Strict-Transport-Security`: Tells browsers to prefer HTTPS - `X-Content-Type-Options`: Avoids [MIME sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing) - `X-DNS-Prefetch-Control`: Controls DNS prefetching - `X-Download-Options`: Forces downloads to be saved (Internet Explorer only) - `X-Frame-Options`: Legacy header that mitigates [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) attacks - `X-Permitted-Cross-Domain-Policies`: Controls cross-domain behavior for Adobe products, like Acrobat - `X-Powered-By`: Info about the web server. Removed because it could be used in simple attacks - `X-XSS-Protection`: Legacy header that tries to mitigate [XSS attacks](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting), but makes things worse, so Helmet disables it Each header can be configured or disabled. To read more about it please go to [its documentation website][helmet]. Install Helmet like any other module: ```bash $ npm install helmet ``` Then to use it in your code: ```js // ... const helmet = require('helmet') app.use(helmet()) // ... ``` ## Reduce fingerprinting It can help to provide an extra layer of security to reduce the ability of attackers to determine the software that a server uses, known as "fingerprinting." Though not a security issue itself, reducing the ability to fingerprint an application improves its overall security posture. Server software can be fingerprinted by quirks in how it responds to specific requests, for example in the HTTP response headers. By default, Express sends the `X-Powered-By` response header that you can disable using the `app.disable()` method: ```js app.disable('x-powered-by') ``` {% capture powered-advisory %} Disabling the `X-Powered-By header` does not prevent a sophisticated attacker from determining that an app is running Express. It may discourage a casual exploit, but there are other ways to determine an app is running Express. {% endcapture %} {% include admonitions/note.html content=powered-advisory %} Express also sends its own formatted "404 Not Found" messages and formatter error response messages. These can be changed by [adding your own not found handler](/en/starter/faq.html#how-do-i-handle-404-responses) and [writing your own error handler](/en/guide/error-handling.html#writing-error-handlers): ```js // last app.use calls right before app.listen(): // custom 404 app.use((req, res, next) => { res.status(404).send("Sorry can't find that!") }) // custom error handler app.use((err, req, res, next) => { console.error(err.stack) res.status(500).send('Something broke!') }) ``` ## Use cookies securely To ensure cookies don't open your app to exploits, don't use the default session cookie name and set cookie security options appropriately. There are two main middleware cookie session modules: * [express-session](https://www.npmjs.com/package/express-session) that replaces `express.session` middleware built-in to Express 3.x. * [cookie-session](https://www.npmjs.com/package/cookie-session) that replaces `express.cookieSession` middleware built-in to Express 3.x. The main difference between these two modules is how they save cookie session data. The [express-session](https://www.npmjs.com/package/express-session) middleware stores session data on the server; it only saves the session ID in the cookie itself, not session data. By default, it uses in-memory storage and is not designed for a production environment. In production, you'll need to set up a scalable session-store; see the list of [compatible session stores](https://github.com/expressjs/session#compatible-session-stores). In contrast, [cookie-session](https://www.npmjs.com/package/cookie-session) middleware implements cookie-backed storage: it serializes the entire session to the cookie, rather than just a session key. Only use it when session data is relatively small and easily encoded as primitive values (rather than objects). Although browsers are supposed to support at least 4096 bytes per cookie, to ensure you don't exceed the limit, don't exceed a size of 4093 bytes per domain. Also, be aware that the cookie data will be visible to the client, so if there is any reason to keep it secure or obscure, then `express-session` may be a better choice. ### Don't use the default session cookie name Using the default session cookie name can open your app to attacks. The security issue posed is similar to `X-Powered-By`: a potential attacker can use it to fingerprint the server and target attacks accordingly. To avoid this problem, use generic cookie names; for example using [express-session](https://www.npmjs.com/package/express-session) middleware: ```js const session = require('express-session') app.set('trust proxy', 1) // trust first proxy app.use(session({ secret: 's3Cur3', name: 'sessionId' })) ``` ### Set cookie security options Set the following cookie options to enhance security: * `secure` - Ensures the browser only sends the cookie over HTTPS. * `httpOnly` - Ensures the cookie is sent only over HTTP(S), not client JavaScript, helping to protect against cross-site scripting attacks. * `domain` - indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next. * `path` - indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request. * `expires` - use to set expiration date for persistent cookies. Here is an example using [cookie-session](https://www.npmjs.com/package/cookie-session) middleware: ```js const session = require('cookie-session') const express = require('express') const app = express() const expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour app.use(session({ name: 'session', keys: ['key1', 'key2'], cookie: { secure: true, httpOnly: true, domain: 'example.com', path: 'foo/bar', expires: expiryDate } })) ``` ## Prevent brute-force attacks against authorization Make sure login endpoints are protected to make private data more secure. A simple and powerful technique is to block authorization attempts using two metrics: 1. The number of consecutive failed attempts by the same user name and IP address. 1. The number of failed attempts from an IP address over some long period of time. For example, block an IP address if it makes 100 failed attempts in one day. [rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) package provides tools to make this technique easy and fast. You can find [an example of brute-force protection in the documentation](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection) ## Ensure your dependencies are secure Using npm to manage your application's dependencies is powerful and convenient. But the packages that you use may contain critical security vulnerabilities that could also affect your application. The security of your app is only as strong as the "weakest link" in your dependencies. Since npm@6, npm automatically reviews every install request. Also, you can use `npm audit` to analyze your dependency tree. ```bash $ npm audit ``` If you want to stay more secure, consider [Snyk](https://snyk.io/). Snyk offers both a [command-line tool](https://www.npmjs.com/package/snyk) and a [Github integration](https://snyk.io/docs/github) that checks your application against [Snyk's open source vulnerability database](https://snyk.io/vuln/) for any known vulnerabilities in your dependencies. Install the CLI as follows: ```bash $ npm install -g snyk $ cd your-app ``` Use this command to test your application for vulnerabilities: ```bash $ snyk test ``` ### Avoid other known vulnerabilities Keep an eye out for [Node Security Project](https://npmjs.com/advisories) or [Snyk](https://snyk.io/vuln/) advisories that may affect Express or other modules that your app uses. In general, these databases are excellent resources for knowledge and tools about Node security. Finally, Express apps—like any other web apps—can be vulnerable to a variety of web-based attacks. Familiarize yourself with known [web vulnerabilities](https://www.owasp.org/www-project-top-ten/) and take precautions to avoid them. ## Additional considerations Here are some further recommendations from the excellent [Node.js Security Checklist](https://blog.risingstack.com/node-js-security-checklist/). Refer to that blog post for all the details on these recommendations: * Always filter and sanitize user input to protect against cross-site scripting (XSS) and command injection attacks. * Defend against SQL injection attacks by using parameterized queries or prepared statements. * Use the open-source [sqlmap](http://sqlmap.org/) tool to detect SQL injection vulnerabilities in your app. * Use the [nmap](https://nmap.org/) and [sslyze](https://github.com/nabla-c0d3/sslyze) tools to test the configuration of your SSL ciphers, keys, and renegotiation as well as the validity of your certificate. * Use [safe-regex](https://www.npmjs.com/package/safe-regex) to ensure your regular expressions are not susceptible to [regular expression denial of service](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS) attacks. [helmet]: https://helmetjs.github.io/ --- --- layout: page title: Developing template engines for Express description: Learn how to develop custom template engines for Express.js using app.engine(), with examples on creating and integrating your own template rendering logic. menu: advanced order: 1 redirect_from: "/advanced/developing-template-engines.html" --- # Developing template engines for Express Use the `app.engine(ext, callback)` method to create your own template engine. `ext` refers to the file extension, and `callback` is the template engine function, which accepts the following items as parameters: the location of the file, the options object, and the callback function. The following code is an example of implementing a very simple template engine for rendering `.ntl` files. ```js const fs = require('fs') // this engine requires the fs module app.engine('ntl', (filePath, options, callback) => { // define the template engine fs.readFile(filePath, (err, content) => { if (err) return callback(err) // this is an extremely simple template engine const rendered = content.toString() .replace('#title#', `${options.title}`) .replace('#message#', `

${options.message}

`) return callback(null, rendered) }) }) app.set('views', './views') // specify the views directory app.set('view engine', 'ntl') // register the template engine ``` Your app will now be able to render `.ntl` files. Create a file named `index.ntl` in the `views` directory with the following content. ```pug #title# #message# ``` Then, create the following route in your app. ```js app.get('/', (req, res) => { res.render('index', { title: 'Hey', message: 'Hello there!' }) }) ``` When you make a request to the home page, `index.ntl` will be rendered as HTML. --- --- layout: page title: Health Checks and Graceful Shutdown description: Learn how to implement health checks and graceful shutdown in Express apps to enhance reliability, manage deployments, and integrate with load balancers like Kubernetes. menu: advanced order: 5 redirect_from: "/advanced/healthcheck-graceful-shutdown.html" --- # Health Checks and Graceful Shutdown ## Graceful shutdown When you deploy a new version of your application, you must replace the previous version. The process manager you're using will first send a SIGTERM signal to the application to notify it that it will be killed. Once the application gets this signal, it should stop accepting new requests, finish all the ongoing requests, clean up the resources it used, including database connections and file locks then exit. ### Example ```js const server = app.listen(port) process.on('SIGTERM', () => { debug('SIGTERM signal received: closing HTTP server') server.close(() => { debug('HTTP server closed') }) }) ``` ## Health checks A load balancer uses health checks to determine if an application instance is healthy and can accept requests. For example, [Kubernetes has two health checks](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/): * `liveness`, that determines when to restart a container. * `readiness`, that determines when a container is ready to start accepting traffic. When a pod is not ready, it is removed from the service load balancers. --- --- layout: page title: Express security updates description: Review the latest security updates and patches for Express.js, including detailed vulnerability lists for different versions to help maintain a secure application. menu: advanced order: 2 redirect_from: "/advanced/security-updates.html" --- # Security updates
Node.js vulnerabilities directly affect Express. Therefore, [keep a watch on Node.js vulnerabilities](https://nodejs.org/en/blog/vulnerability/) and make sure you are using the latest stable version of Node.js.
The list below enumerates the Express vulnerabilities that were fixed in the specified version update. {% capture security-policy %} If you believe you have discovered a security vulnerability in Express, please see [Security Policies and Procedures](/{{page.lang}}/resources/contributing.html#security-policies-and-procedures). {% endcapture %} {% include admonitions/note.html content=security-policy %} ## 4.x * 4.21.2 * The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w). * 4.21.1 * The dependency `cookie` has been updated to address a [vulnerability](https://github.com/jshttp/cookie/security/advisories/GHSA-pxg6-pf52-xh8x), This may affect your application if you use `res.cookie`. * 4.20.0 * Fixed XSS vulnerability in `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-qw6h-vgh9-j6wx), [CVE-2024-43796](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-43796)). * The dependency `serve-static` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-cm22-4g7w-348p). * The dependency `send` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg). * The dependency `path-to-regexp` has been updated to address a [vulnerability](https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-9wv6-86v2-598j). * The dependency `body-parser` has been updated to addres a [vulnerability](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7), This may affect your application if you had url enconding activated. * 4.19.0, 4.19.1 * Fixed open redirect vulnerability in `res.location` and `res.redirect` ([advisory](https://github.com/expressjs/express/security/advisories/GHSA-rv95-896h-c2vc), [CVE-2024-29041](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-29041)). * 4.17.3 * The dependency `qs` has been updated to address a [vulnerability](https://github.com/advisories/GHSA-hrpp-h998-j3pp). This may affect your application if the following APIs are used: `req.query`, `req.body`, `req.param`. * 4.16.0 * The dependency `forwarded` has been updated to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`. * The dependency `mime` has been updated to address a [vulnerability](https://npmjs.com/advisories/535), but this issue does not impact Express. * The dependency `send` has been updated to provide a protection against a [Node.js 8.5.0 vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). This only impacts running Express on the specific Node.js version 8.5.0. * 4.15.5 * The dependency `debug` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express. * The dependency `fresh` has been updated to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`. * 4.15.3 * The dependency `ms` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`. * 4.15.2 * The dependency `qs` has been updated to address a [vulnerability](https://snyk.io/vuln/npm:qs:20170213), but this issue does not impact Express. Updating to 4.15.2 is a good practice, but not required to address the vulnerability. * 4.11.1 * Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile` * 4.10.7 * Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). * 4.8.8 * Fixed directory traversal vulnerabilities in `express.static` ([advisory](http://npmjs.com/advisories/32) , [CVE-2014-6394](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6394)). * 4.8.4 * Node.js 0.10 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. * 4.8.0 * Sparse arrays that have extremely high indexes in the query string could cause the process to run out of memory and crash the server. * Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. ## 3.x
**Express 3.x IS END-OF-LIFE AND NO LONGER MAINTAINED** Known and unknown security and performance issues in 3.x have not been addressed since the last update (1 August, 2015). It is highly recommended to use the latest version of Express. If you are unable to upgrade past 3.x, please consider [Commercial Support Options](/{{ page.lang }}/support#commercial-support-options).
* 3.19.1 * Fixed root path disclosure vulnerability in `express.static`, `res.sendfile`, and `res.sendFile` * 3.19.0 * Fixed open redirect vulnerability in `express.static` ([advisory](https://npmjs.com/advisories/35), [CVE-2015-1164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1164)). * 3.16.10 * Fixed directory traversal vulnerabilities in `express.static`. * 3.16.6 * Node.js 0.10 can leak `fd`s in certain situations that affect `express.static` and `res.sendfile`. Malicious requests could cause `fd`s to leak and eventually lead to `EMFILE` errors and server unresponsiveness. * 3.16.0 * Sparse arrays that have extremely high indexes in query string could cause the process to run out of memory and crash the server. * Extremely nested query string objects could cause the process to block and make the server unresponsive temporarily. * 3.3.0 * The 404 response of an unsupported method override attempt was susceptible to cross-site scripting attacks. --- --- layout: api version: 5x title: Express 5.x - API Reference description: Access the API reference for Express.js detailing all modules, methods, and properties for building web applications with this version. menu: api redirect_from: "/api.html" ---

5.x API

{% include api/en/5x/express.md %} {% include api/en/5x/app.md %} {% include api/en/5x/req.md %} {% include api/en/5x/res.md %} {% include api/en/5x/router.md %}
--- --- layout: post title: Express Blog Posts description: Explore the latest articles, announcements, and updates from the Express.js team and community on the Express blog. menu: blog redirect_from: "/blog/posts.html" --- Want to write a post? See the submission [guidelines.](/en/blog/write-post.html) {% if site.posts.size != 0 %}
{% for post in site.posts %}
{% include blog/authors.html authors=post.authors %}
{{ post.date | date:"%b %d, %Y" }}
{{post.excerpt | truncate: 240 | markdownify }}
{% endfor %}
{% else %} There are currently no blog posts. {% endif %} --- --- layout: post title: How to write a blog post description: Learn how to propose and write a blog post for the Express.js blog, including submission guidelines and steps to contribute your content. menu: blog redirect_from: "/blog/write.html" --- ![Blogger]({{site.url}}/images/blogger.jpg) If you have an idea for a blog post, follow these steps to propose it and potentially get it published! 1. ### Propose your post Before taking the time to write a post, please confirm that we will be able to publish it. We're looking for topics specifically related to Express, and so we want to pre-approve all posts. For the moment, this means we aren't accepting any unsolicited posts. To propose a blog post, [open an issue](https://github.com/expressjs/expressjs.com/issues) entitled `Blog post proposal: `. 1. ### Fork the repository If the Express TC accepts your proposal, start to write your post by forking the [expressjs.com](https://github.com/expressjs/expressjs.com) repository and cloning it to your local machine. Once you open a pull request, you'll be able to preview your post on GitHub. See step six below. Optional: To run the site locally and preview your post before opening a PR, see the [setup instructions in the README](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#expressjscom). {: .doc-box .doc-info} 1. ### Create a new file Create a new file in the `_posts` directory named using following the format: `YYYY-MM-DD-title.md`. 1. ### Add the required front matter Copy the following front matter, including the dotted lines, and paste it at the top of file you just created. Replace the placeholder values with as desired. ```markdown --- title: sub_title: description: tags: authors: - name: github: --- ``` The `github` property of an author is optional. Including your username only (not your full profile URL) will ensure that your blog post links out to it. 2. ### Add your content Finally, start writing your content below the front matter. Use standard markdown formatting. 1. ### Open a pull request (PR) Once you open a PR, you will be able to preview your results: There will be a section on the page entitled `Deploy Preview for expressjscom-preview ready!` Click the link to see the site rendered from your fork/branch. You can use this feature over multiple commits to refine your post by making a `draft` pull request. Once it's ready for review, switch it to a formal PR. --- --- layout: page title: Express changelog description: Stay updated with the release changelog for Express.js, detailing new features, bug fixes, and important changes across versions. sitemap: false redirect_from: - "/changelog/4x.html" - "en/changelog/4x.html" ---
# Release changelog All the latest updates, improvements, and fixes to Express ## Express v5 {: id="5.x"} ### 5.1.0 - Release date: 2025-03-31 {: id="5.0.1"} The 5.1.0 minor release includes some new features and improvements: * Support for sending responses as Uint8Array * Added support for ETag option in `res.sendFile()` * Added support for adding multiple links with the same rel with `res.links()` * Performance: Use loop for acceptParams * [body-parser@2.2.0](https://github.com/expressjs/body-parser/releases/tag/v2.2.0) * Remove legacy node.js support checks for Brotli & `AsyncLocalStorage` * Remove `unpipe` & `destroy` * [router@2.2.0](https://github.com/pillarjs/router/releases/tag/v2.2.0) * Restore `debug`. Now with the `router` scope instead of `express`. * Remove legacy node.js support checks for `setImmediate` * Deprecate non-native promise support * Remove `after`, `safe-buffer`, `array-flatten`, `setprotoypeof`, `methods`, `utils-merge` * [finalhandler@2.1.0](https://github.com/pillarjs/finalhandler/releases/tag/v2.1.0) * Remove legacy node.js support checks for `headersSent`, `setImmediate`, & http2 support * Remove `unpipe` * Transitioned all remaining dependencies to use `^` ranges instead of locked versions * Add package.json funding field to highlight our OpenCollective * See [Changelog v5.1.0](https://github.com/expressjs/express/releases/tag/v5.1.0) ### 5.0.1 - Release date: 2024-10-08 {: id="5.0.1"} The 5.0.1 patch release includes one security fix: * Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). ### 5.0.0 - Release date: 2024-09-09 {: id="5.0.0"} Check the [migration guide](/{{page.lang}}/guide/migrating-5.html) with all the changes in this new version of Express. ## Express v4 {: id="4.x"} ### 4.21.2 - Release date: 2024-11-06 {: id="4.21.2"} The 4.21.2 patch release includes one security fix: * Update [pillajs/path-to-regexp](https://www.npmjs.com/package/path-to-regexp) to address a [vulnerability](https://github.com/advisories/GHSA-rhx6-c78j-4q9w). ### 4.21.1 - Release date: 2024-10-08 {: id="4.21.1"} The 4.21.1 patch release includes one security fix: * Update [jshttps/cookie](https://www.npmjs.com/package/cookie) to address a [vulnerability](https://github.com/advisories/GHSA-pxg6-pf52-xh8x). ### 4.21.0 - Release date: 2024-09-11 {: id="4.21.0"} The 4.21.0 minor release includes one new feature: * Deprecate `res.location("back")` and `res.redirect("back")` magic string ### 4.20.0 - Release date: 2024-09-10 {: id="4.20.0"} The 4.20.0 minor release includes bug fixes and some new features, including: * The [`res.clearCookie()` method](/{{ page.lang }}/4x/api.html#res.clearCookie) deprecates `options.maxAge` and `options.expires` options. * The [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) removes HTML link rendering. * The [`express.urlencoded()` method](/{{ page.lang }}/4x/api.html#express.urlencoded) method now has a depth level of `32`, whereas it was previously `Infinity`. * Adds support for named matching groups in the routes using a regex * Removes encoding of `\`, `|`, and `^` to align better with URL spec For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4200--2024-09-10) ### 4.19.2 - Release date: 2024-03-25 {: id="4.19.2"} * Improved fix for open redirect allow list bypass For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4192--2024-03-25) ### 4.19.1 - Release date: 2024-03-20 {: id="4.19.1"} * Allow passing non-strings to res.location with new encoding handling checks For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4191--2024-03-20) ### 4.19.0 - Release date: 2024-03-20 {: id="4.19.0"} * Prevent open redirect allow list bypass due to encodeurl * deps: cookie@0.6.0 For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4190--2024-03-20) ### 4.18.3 - Release date: 2024-02-29 {: id="4.18.3"} The 4.18.3 patch release includes the following bug fix:
  • Fix routing requests without method. ([commit](https://github.com/expressjs/express/commit/74beeac0718c928b4ba249aba3652c52fbe32ca8))
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4183--2024-02-26) ### 4.18.2 - Release date: 2022-10-08 {: id="4.18.2"} The 4.18.2 patch release includes the following bug fix:
  • Fix regression routing a large stack in a single route. ([commit](https://github.com/expressjs/express/commit/7ec5dd2b3c5e7379f68086dae72859f5573c8b9b))
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4182--2022-10-08) ### 4.18.1 - Release date: 2022-04-29 {: id="4.18.1"} The 4.18.1 patch release includes the following bug fix:
  • Fix the condition where if an Express application is created with a very large stack of routes, and all of those routes are sync (call `next()` synchronously), then the request processing may hang.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4181--2022-04-29). ### 4.18.0 - Release date: 2022-04-25 {: id="4.18.0"} The 4.18.0 minor release includes bug fixes and some new features, including:
  • The [`app.get()` method](/{{ page.lang }}/4x/api.html#app.get) and the [`app.set()` method](/{{ page.lang }}/4x/api.html#app.set) now ignores properties directly on `Object.prototype` when getting a setting value.
  • The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now accepts a "priority" option to set the Priority attribute on the Set-Cookie response header.
  • The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now rejects an Invalid Date object provided as the "expires" option.
  • The [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) now works when `null` or `undefined` is explicitly provided as the "maxAge" argument.
  • Starting with this version, Express supports Node.js 18.x.
  • The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts a "root" option to match [`res.sendFile()`](/{{ page.lang }}/4x/api.html#res.sendFile).
  • The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) can be supplied with an `options` object without providing a `filename` argument, simplifying calls when the default `filename` is desired.
  • The [`res.format()` method](/{{ page.lang }}/4x/api.html#res.format) now invokes the provided "default" handler with the same arguments as the type handlers (`req`, `res`, and `next`).
  • The [`res.send()` method](/{{ page.lang }}/4x/api.html#res.send) will not attempt to send a response body when the response code is set to 205.
  • The default error handler will now remove certain response headers that will break the error response rendering, if they were set previously.
  • The status code 425 is now represented as the standard "Too Early" instead of "Unordered Collection".
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4180--2022-04-25). ### 4.17.3 - Release date: 2022-02-16 {: id="4.17.3"} The 4.17.3 patch release includes one bug fix:
  • Update to [qs module](https://www.npmjs.com/package/qs) for a fix around parsing `__proto__` properties.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4173--2022-02-16). ### 4.17.2 - Release date: 2021-12-16 {: id="4.17.2"} The 4.17.2 patch release includes the following bug fixes:
  • Fix handling of `undefined` in `res.jsonp` when a callback is provided.
  • Fix handling of `undefined` in `res.json` and `res.jsonp` when `"json escape"` is enabled.
  • Fix handling of invalid values to the `maxAge` option of `res.cookie()`.
  • Update to [jshttp/proxy-addr module](https://www.npmjs.com/package/proxy-addr) to use `req.socket` over deprecated `req.connection`.
  • Starting with this version, Express supports Node.js 14.x.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4172--2021-12-16). ### 4.17.1 - Release date: 2019-05-25 {: id="4.17.1"} The 4.17.1 patch release includes one bug fix:
  • The change to the `res.status()` API has been reverted due to causing regressions in existing Express 4 applications.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4171--2019-05-25). ### 4.17.0 - Release date: 2019-05-16 {: id="4.17.0"} The 4.17.0 minor release includes bug fixes and some new features, including:
  • The `express.raw()` and `express.text()` middleware have been added to provide request body parsing for more raw request payloads. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers.
  • The `res.cookie()` API now supports the `"none"` value for the `sameSite` option.
  • When the `"trust proxy"` setting is enabled, the `req.hostname` now supports multiple `X-Forwarded-For` headers in a request.
  • Starting with this version, Express supports Node.js 10.x and 12.x.
  • The `res.sendFile()` API now provides and more immediate and easier to understand error when a non-string is passed as the `path` argument.
  • The `res.status()` API now provides and more immediate and easier to understand error when `null` or `undefined` is passed as the argument.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4170--2019-05-16). ### 4.16.4 - Release date: 2018-10-10 {: id="4.16.4"} The 4.16.4 patch release includes various bug fixes:
  • Fix issue where `"Request aborted"` may be logged in `res.sendfile`.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4164--2018-10-10). ### 4.16.3 - Release date: 2018-03-12 {: id="4.16.3"} The 4.16.3 patch release includes various bug fixes:
  • Fix issue where a plain `%` at the end of the url in the `res.location` method or the `res.redirect` method would not get encoded as `%25`.
  • Fix issue where a blank `req.url` value can result in a thrown error within the default 404 handling.
  • Fix the generated HTML document for `express.static` redirect responses to properly include ``.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4163--2018-03-12). ### 4.16.2 - Release date: 2017-10-09 {: id="4.16.2"} The 4.16.2 patch release includes a regression bug fix:
  • Fix a `TypeError` that can occur in the `res.send` method when a `Buffer` is passed to `res.send` and the `ETag` header is already set on the response.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4162--2017-10-09). ### 4.16.1 - Release date: 2017-09-29 {: id="4.16.1"} The 4.16.1 patch release includes a regression bug fix:
  • Update to [pillarjs/send module](https://www.npmjs.com/package/send) to fix an edge case scenario regression that affected certain users of `express.static`.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4161--2017-09-29). ### 4.16.0 - Release date: 2017-09-28 {: id="4.16.0"} The 4.16.0 minor release includes security updates, bug fixes, performance enhancements, and some new features, including:
  • Update to [jshttp/forwarded module](https://www.npmjs.com/package/forwarded) to address a [vulnerability](https://npmjs.com/advisories/527). This may affect your application if the following APIs are used: `req.host`, `req.hostname`, `req.ip`, `req.ips`, `req.protocol`.
  • Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://npmjs.com/advisories/535) in the `mime` dependency. This may affect your application if untrusted string input is passed to the following APIs: `res.type()`.
  • The [pillarjs/send module](https://www.npmjs.com/package/send) has implemented a protection against the Node.js 8.5.0 [vulnerability](https://nodejs.org/en/blog/vulnerability/september-2017-path-validation/). Using any prior version of Express with Node.js 8.5.0 (that specific Node.js version) will make the following APIs vulnerable: `express.static`, `res.sendfile`, and `res.sendFile`.
  • Starting with this version, Express supports Node.js 8.x.
  • The new setting `"json escape"` can be enabled to escape characters in `res.json()`, `res.jsonp()` and `res.send()` responses that can trigger clients to sniff the response as HTML instead of honoring the `Content-Type`. This can help protect an Express app from a class of persistent XSS-based attacks.
  • The [`res.download()` method](/{{ page.lang }}/4x/api.html#res.download) now accepts an optional `options` object.
  • The `express.json()` and `express.urlencoded()` middleware have been added to provide request body parsing support out-of-the-box. This uses the [expressjs/body-parser module](https://www.npmjs.com/package/body-parser) module underneath, so apps that are currently requiring the module separately can switch to the built-in parsers.
  • The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support setting the `immutable` directive on the `Cache-Control` header. Setting this header with an appropriate `maxAge` will prevent supporting web browsers from sending any request to the server when the file is still in their cache.
  • The [pillarjs/send module](https://www.npmjs.com/package/send) has an updated list of MIME types to better set the `Content-Type` of more files. There are 70 new types for file extensions.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4160--2017-09-28). ### 4.15.5 - Release date: 2017-09-24 {: id="4.15.5"} The 4.15.5 patch release includes security updates, some minor performance enhancements, and a bug fix:
  • Update to [debug module](https://www.npmjs.com/package/debug) to address a [vulnerability](https://snyk.io/vuln/npm:debug:20170905), but this issue does not impact Express.
  • Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) to address a [vulnerability](https://npmjs.com/advisories/526). This will affect your application if the following APIs are used: `express.static`, `req.fresh`, `res.json`, `res.jsonp`, `res.send`, `res.sendfile` `res.sendFile`, `res.sendStatus`.
  • Update to [jshttp/fresh module](https://www.npmjs.com/package/fresh) fixes handling of modified headers with invalid dates and makes parsing conditional headers (like `If-None-Match`) faster.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4155--2017-09-24). ### 4.15.4 - Release date: 2017-08-06 {: id="4.15.4"} The 4.15.4 patch release includes some minor bug fixes:
  • Fix array being set for `"trust proxy"` value being manipulated in certain conditions.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4154--2017-08-06). ### 4.15.3 - Release date: 2017-05-16 {: id="4.15.3"} The 4.15.3 patch release includes a security update and some minor bug fixes:
  • Update a dependency of the [pillarjs/send module](https://www.npmjs.com/package/send) to address a [vulnerability](https://snyk.io/vuln/npm:ms:20170412). This may affect your application if untrusted string input is passed to the `maxAge` option in the following APIs: `express.static`, `res.sendfile`, and `res.sendFile`.
  • Fix error when `res.set` cannot add charset to `Content-Type`.
  • Fix missing `` in HTML document.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4153--2017-05-16). ### 4.15.2 - Release date: 2017-03-06 {: id="4.15.2"} The 4.15.2 patch release includes a minor bug fix:
  • Fix regression parsing keys starting with `[` in the extended (default) query parser.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4152--2017-03-06). ### 4.15.1 - Release date: 2017-03-05 {: id="4.15.1"} The 4.15.1 patch release includes a minor bug fix:
  • Fix compatibility issue when using the datejs 1.x library where the [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) would incorrectly respond with 412 Precondition Failed.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4151--2017-03-05). ### 4.15.0 - Release date: 2017-03-01 {: id="4.15.0"} The 4.15.0 minor release includes bug fixes, performance improvements, and other minor feature additions, including:
  • Starting with this version, Express supports Node.js 7.x.
  • The [`express.static()` middleware](/{{ page.lang }}/4x/api.html#express.static) and [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now support the `If-Match` and `If-Unmodified-Since` request headers.
  • Update to [jshttp/etag module](https://www.npmjs.com/package/etag) to generate the default ETags for responses which work when Node.js has [FIPS-compliant crypto enabled](https://nodejs.org/dist/latest/docs/api/cli.html#cli_enable_fips).
  • Various auto-generated HTML responses like the default not found and error handlers will respond with complete HTML 5 documents and additional security headers.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4150--2017-03-01). ### 4.14.1 - Release date: 2017-01-28 {: id="4.14.1"} The 4.14.1 patch release includes bug fixes and performance improvements, including:
  • Update to [pillarjs/finalhandler module](https://www.npmjs.com/package/finalhandler) fixes an exception when Express handles an `Error` object which has a `headers` property that is not an object.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4141--2017-01-28). ### 4.14.0 - Release date: 2016-06-16 {: id="4.14.0"} The 4.14.0 minor release includes bug fixes, security update, performance improvements, and other minor feature additions, including:
  • Starting with this version, Express supports Node.js 6.x.
  • Update to [jshttp/negotiator module](https://www.npmjs.com/package/negotiator) fixes a [regular expression denial of service vulnerability](https://npmjs.com/advisories/106).
  • The [`res.sendFile()` method](/{{ page.lang }}/4x/api.html#res.sendFile) now accepts two new options: `acceptRanges` and `cacheControl`. - `acceptRanges` (defaut is `true`), enables or disables accepting ranged requests. When disabled, the response does not send the `Accept-Ranges` header and ignores the contents of the `Range` request header. - `cacheControl`, (default is `true`), enables or disables the `Cache-Control` response header. Disabling it will ignore the `maxAge` option. - `res.sendFile` has also been updated to handle `Range` header and redirections better.
  • The [`res.location()` method](/{{ page.lang }}/4x/api.html#res.location) and [`res.redirect()` method](/{{ page.lang }}/4x/api.html#res.redirect) will now URL-encode the URL string, if it is not already encoded.
  • The performance of the [`res.json()` method](/{{ page.lang }}/4x/api.html#res.json) and [`res.jsonp()` method](/{{ page.lang }}/4x/api.html#res.jsonp) have been improved in the common cases.
  • The [jshttp/cookie module](https://www.npmjs.com/package/cookie) (in addition to a number of other improvements) has been updated and now the [`res.cookie()` method](/{{ page.lang }}/4x/api.html#res.cookie) supports the `sameSite` option to let you specify the [SameSite cookie attribute](https://tools.ietf.org/html/draft-west-first-party-cookies-07). {% capture note-4-14-0 %} This attribute has not yet been fully standardized, may change in the future, and many clients may ignore it. {% endcapture %} {% include admonitions/note.html content=note-4-14-0 %} The possible value for the `sameSite` option are: - `true`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement. - `false`, which does not set the `SameSite` attribute. - `'lax'`, which sets the `SameSite` attribute to `Lax` for lax same site enforcement. - `'strict'`, which sets the `SameSite` attribute to `Strict` for strict same site enforcement.
  • Absolute path checking on Windows, which was incorrect for some cases, has been fixed.
  • IP address resolution with proxies has been greatly improved.
  • The [`req.range()` method](/{{ page.lang }}/4x/api.html#req.range) options object now supports a `combine` option (`false` by default), which when `true`, combines overlapping and adjacent ranges and returns them as if they were specified that way in the header.
For a complete list of changes in this release, see [History.md](https://github.com/expressjs/express/blob/master/History.md#4140--2016-06-16).
--- --- layout: page title: Express behind proxies description: Learn how to configure Express.js applications to work correctly behind reverse proxies, including using the trust proxy setting to handle client IP addresses. menu: guide order: 8 redirect_from: "/guide/behind-proxies.html" --- # Express behind proxies When running an Express app behind a reverse proxy, some of the Express APIs may return different values than expected. In order to adjust for this, the `trust proxy` application setting may be used to expose information provided by the reverse proxy in the Express APIs. The most common issue is express APIs that expose the client's IP address may instead show an internal IP address of the reverse proxy.
When configuring the `trust proxy` setting, it is important to understand the exact setup of the reverse proxy. Since this setting will trust values provided in the request, it is important that the combination of the setting in Express matches how the reverse proxy operates.
The application setting `trust proxy` may be set to one of the values listed in the following table.
TypeValue
Boolean If `true`, the client's IP address is understood as the left-most entry in the `X-Forwarded-For` header. If `false`, the app is understood as directly facing the client and the client's IP address is derived from `req.socket.remoteAddress`. This is the default setting.
When setting to `true`, it is important to ensure that the last reverse proxy trusted is removing/overwriting all of the following HTTP headers: `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`, otherwise it may be possible for the client to provide any value.
IP addresses An IP address, subnet, or an array of IP addresses and subnets to trust as being a reverse proxy. The following list shows the pre-configured subnet names: * loopback - `127.0.0.1/8`, `::1/128` * linklocal - `169.254.0.0/16`, `fe80::/10` * uniquelocal - `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7` You can set IP addresses in any of the following ways: ```js app.set('trust proxy', 'loopback') // specify a single subnet app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array ``` When specified, the IP addresses or the subnets are excluded from the address determination process, and the untrusted IP address nearest to the application server is determined as the client's IP address. This works by checking if `req.socket.remoteAddress` is trusted. If so, then each address in `X-Forwarded-For` is checked from right to left until the first non-trusted address.
Number Use the address that is at most `n` number of hops away from the Express application. `req.socket.remoteAddress` is the first hop, and the rest are looked for in the `X-Forwarded-For` header from right to left. A value of `0` means that the first untrusted address would be `req.socket.remoteAddress`, i.e. there is no reverse proxy.
When using this setting, it is important to ensure there are not multiple, different-length paths to the Express application such that the client can be less than the configured number of hops away, otherwise it may be possible for the client to provide any value.
Function Custom trust implementation. ```js app.set('trust proxy', (ip) => { if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs else return false }) ```
Enabling `trust proxy` will have the following impact:
  • The value of [req.hostname](/{{ page.lang }}/api.html#req.hostname) is derived from the value set in the `X-Forwarded-Host` header, which can be set by the client or by the proxy.
  • `X-Forwarded-Proto` can be set by the reverse proxy to tell the app whether it is `https` or `http` or even an invalid name. This value is reflected by [req.protocol](/{{ page.lang }}/api.html#req.protocol).
  • The [req.ip](/{{ page.lang }}/api.html#req.ip) and [req.ips](/{{ page.lang }}/api.html#req.ips) values are populated based on the socket address and `X-Forwarded-For` header, starting at the first untrusted address.
The `trust proxy` setting is implemented using the [proxy-addr](https://www.npmjs.com/package/proxy-addr) package. For more information, see its documentation. --- --- layout: page title: Express database integration description: Discover how to integrate various databases with Express.js applications, including setup examples for MongoDB, MySQL, PostgreSQL, and more. menu: guide order: 11 redirect_from: "/guide/database-integration.html" --- # Database integration Adding the capability to connect databases to Express apps is just a matter of loading an appropriate Node.js driver for the database in your app. This document briefly explains how to add and use some of the most popular Node.js modules for database systems in your Express app: * [Cassandra](#cassandra) * [Couchbase](#couchbase) * [CouchDB](#couchdb) * [LevelDB](#leveldb) * [MySQL](#mysql) * [MongoDB](#mongodb) * [Neo4j](#neo4j) * [Oracle](#oracle) * [PostgreSQL](#postgresql) * [Redis](#redis) * [SQL Server](#sql-server) * [SQLite](#sqlite) * [Elasticsearch](#elasticsearch)
These database drivers are among many that are available. For other options, search on the [npm](https://www.npmjs.com/) site.
## Cassandra **Module**: [cassandra-driver](https://github.com/datastax/nodejs-driver) ### Installation ```bash $ npm install cassandra-driver ``` ### Example ```js const cassandra = require('cassandra-driver') const client = new cassandra.Client({ contactPoints: ['localhost'] }) client.execute('select key from system.local', (err, result) => { if (err) throw err console.log(result.rows[0]) }) ``` ## Couchbase **Module**: [couchnode](https://github.com/couchbase/couchnode) ### Installation ```bash $ npm install couchbase ``` ### Example ```js const couchbase = require('couchbase') const bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName') // add a document to a bucket bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, (err, result) => { if (err) { console.log(err) } else { console.log(result) } }) // get all documents with shoe size 13 const n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1' const query = N1qlQuery.fromString(n1ql) bucket.query(query, [13], (err, result) => { if (err) { console.log(err) } else { console.log(result) } }) ``` ## CouchDB **Module**: [nano](https://github.com/dscape/nano) ### Installation ```bash $ npm install nano ``` ### Example ```js const nano = require('nano')('http://localhost:5984') nano.db.create('books') const books = nano.db.use('books') // Insert a book document in the books database books.insert({ name: 'The Art of war' }, null, (err, body) => { if (err) { console.log(err) } else { console.log(body) } }) // Get a list of all books books.list((err, body) => { if (err) { console.log(err) } else { console.log(body.rows) } }) ``` ## LevelDB **Module**: [levelup](https://github.com/rvagg/node-levelup) ### Installation ```bash $ npm install level levelup leveldown ``` ### Example ```js const levelup = require('levelup') const db = levelup('./mydb') db.put('name', 'LevelUP', (err) => { if (err) return console.log('Ooops!', err) db.get('name', (err, value) => { if (err) return console.log('Ooops!', err) console.log(`name=${value}`) }) }) ``` ## MySQL **Module**: [mysql](https://github.com/felixge/node-mysql/) ### Installation ```bash $ npm install mysql ``` ### Example ```js const mysql = require('mysql') const connection = mysql.createConnection({ host: 'localhost', user: 'dbuser', password: 's3kreee7', database: 'my_db' }) connection.connect() connection.query('SELECT 1 + 1 AS solution', (err, rows, fields) => { if (err) throw err console.log('The solution is: ', rows[0].solution) }) connection.end() ``` ## MongoDB **Module**: [mongodb](https://github.com/mongodb/node-mongodb-native) ### Installation ```bash $ npm install mongodb ``` ### Example (v2.*) ```js const MongoClient = require('mongodb').MongoClient MongoClient.connect('mongodb://localhost:27017/animals', (err, db) => { if (err) throw err db.collection('mammals').find().toArray((err, result) => { if (err) throw err console.log(result) }) }) ``` ### Example (v3.*) ```js const MongoClient = require('mongodb').MongoClient MongoClient.connect('mongodb://localhost:27017/animals', (err, client) => { if (err) throw err const db = client.db('animals') db.collection('mammals').find().toArray((err, result) => { if (err) throw err console.log(result) }) }) ``` If you want an object model driver for MongoDB, look at [Mongoose](https://github.com/LearnBoost/mongoose). ## Neo4j **Module**: [neo4j-driver](https://github.com/neo4j/neo4j-javascript-driver) ### Installation ```bash $ npm install neo4j-driver ``` ### Example ```js const neo4j = require('neo4j-driver') const driver = neo4j.driver('neo4j://localhost:7687', neo4j.auth.basic('neo4j', 'letmein')) const session = driver.session() session.readTransaction((tx) => { return tx.run('MATCH (n) RETURN count(n) AS count') .then((res) => { console.log(res.records[0].get('count')) }) .catch((error) => { console.log(error) }) }) ``` ## Oracle **Module**: [oracledb](https://github.com/oracle/node-oracledb) ### Installation NOTE: [See installation prerequisites](https://github.com/oracle/node-oracledb#-installation). ```bash $ npm install oracledb ``` ### Example ```js const oracledb = require('oracledb') const config = { user: '', password: '', connectString: 'localhost:1521/orcl' } async function getEmployee (empId) { let conn try { conn = await oracledb.getConnection(config) const result = await conn.execute( 'select * from employees where employee_id = :id', [empId] ) console.log(result.rows[0]) } catch (err) { console.log('Ouch!', err) } finally { if (conn) { // conn assignment worked, need to close await conn.close() } } } getEmployee(101) ``` ## PostgreSQL **Module**: [pg-promise](https://github.com/vitaly-t/pg-promise) ### Installation ```bash $ npm install pg-promise ``` ### Example ```js const pgp = require('pg-promise')(/* options */) const db = pgp('postgres://username:password@host:port/database') db.one('SELECT $1 AS value', 123) .then((data) => { console.log('DATA:', data.value) }) .catch((error) => { console.log('ERROR:', error) }) ``` ## Redis **Module**: [redis](https://github.com/mranney/node_redis) ### Installation ```bash $ npm install redis ``` ### Example ```js const redis = require('redis') const client = redis.createClient() client.on('error', (err) => { console.log(`Error ${err}`) }) client.set('string key', 'string val', redis.print) client.hset('hash key', 'hashtest 1', 'some value', redis.print) client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print) client.hkeys('hash key', (err, replies) => { console.log(`${replies.length} replies:`) replies.forEach((reply, i) => { console.log(` ${i}: ${reply}`) }) client.quit() }) ``` ## SQL Server **Module**: [tedious](https://github.com/tediousjs/tedious) ### Installation ```bash $ npm install tedious ``` ### Example ```js const Connection = require('tedious').Connection const Request = require('tedious').Request const config = { server: 'localhost', authentication: { type: 'default', options: { userName: 'your_username', // update me password: 'your_password' // update me } } } const connection = new Connection(config) connection.on('connect', (err) => { if (err) { console.log(err) } else { executeStatement() } }) function executeStatement () { request = new Request("select 123, 'hello world'", (err, rowCount) => { if (err) { console.log(err) } else { console.log(`${rowCount} rows`) } connection.close() }) request.on('row', (columns) => { columns.forEach((column) => { if (column.value === null) { console.log('NULL') } else { console.log(column.value) } }) }) connection.execSql(request) } ``` ## SQLite **Module**: [sqlite3](https://github.com/mapbox/node-sqlite3) ### Installation ```bash $ npm install sqlite3 ``` ### Example ```js const sqlite3 = require('sqlite3').verbose() const db = new sqlite3.Database(':memory:') db.serialize(() => { db.run('CREATE TABLE lorem (info TEXT)') const stmt = db.prepare('INSERT INTO lorem VALUES (?)') for (let i = 0; i < 10; i++) { stmt.run(`Ipsum ${i}`) } stmt.finalize() db.each('SELECT rowid AS id, info FROM lorem', (err, row) => { console.log(`${row.id}: ${row.info}`) }) }) db.close() ``` ## Elasticsearch **Module**: [elasticsearch](https://github.com/elastic/elasticsearch-js) ### Installation ```bash $ npm install elasticsearch ``` ### Example ```js const elasticsearch = require('elasticsearch') const client = elasticsearch.Client({ host: 'localhost:9200' }) client.search({ index: 'books', type: 'book', body: { query: { multi_match: { query: 'express js', fields: ['title', 'description'] } } } }).then((response) => { const hits = response.hits.hits }, (error) => { console.trace(error.message) }) ``` --- --- layout: page title: Debugging Express description: Learn how to enable and use debugging logs in Express.js applications by setting the DEBUG environment variable for enhanced troubleshooting. menu: guide order: 7 redirect_from: "/guide/debugging.html" --- # Debugging Express To see all the internal logs used in Express, set the `DEBUG` environment variable to `express:*` when launching your app. ```bash $ DEBUG=express:* node index.js ``` On Windows, use the corresponding command. ```bash > $env:DEBUG = "express:*"; node index.js ``` Running this command on the default app generated by the [express generator](/{{ page.lang }}/starter/generator.html) prints the following output: ```bash $ DEBUG=express:* node ./bin/www express:router:route new / +0ms express:router:layer new / +1ms express:router:route get / +1ms express:router:layer new / +0ms express:router:route new / +1ms express:router:layer new / +0ms express:router:route get / +0ms express:router:layer new / +0ms express:application compile etag weak +1ms express:application compile query parser extended +0ms express:application compile trust proxy false +0ms express:application booting in development mode +1ms express:router use / query +0ms express:router:layer new / +0ms express:router use / expressInit +0ms express:router:layer new / +0ms express:router use / favicon +1ms express:router:layer new / +0ms express:router use / logger +0ms express:router:layer new / +0ms express:router use / jsonParser +0ms express:router:layer new / +1ms express:router use / urlencodedParser +0ms express:router:layer new / +0ms express:router use / cookieParser +0ms express:router:layer new / +0ms express:router use / stylus +90ms express:router:layer new / +0ms express:router use / serveStatic +0ms express:router:layer new / +0ms express:router use / router +0ms express:router:layer new / +1ms express:router use /users router +0ms express:router:layer new /users +0ms express:router use / <anonymous> +0ms express:router:layer new / +0ms express:router use / <anonymous> +0ms express:router:layer new / +0ms express:router use / <anonymous> +0ms express:router:layer new / +0ms ``` When a request is then made to the app, you will see the logs specified in the Express code: ```bash express:router dispatching GET / +4h express:router query : / +2ms express:router expressInit : / +0ms express:router favicon : / +0ms express:router logger : / +1ms express:router jsonParser : / +0ms express:router urlencodedParser : / +1ms express:router cookieParser : / +0ms express:router stylus : / +0ms express:router serveStatic : / +2ms express:router router : / +2ms express:router dispatching GET / +1ms express:view lookup "index.pug" +338ms express:view stat "/projects/example/views/index.pug" +0ms express:view render "/projects/example/views/index.pug" +1ms ``` To see the logs only from the router implementation, set the value of `DEBUG` to `express:router`. Likewise, to see logs only from the application implementation, set the value of `DEBUG` to `express:application`, and so on. ## Applications generated by `express` An application generated by the `express` command uses the `debug` module and its debug namespace is scoped to the name of the application. For example, if you generated the app with `$ express sample-app`, you can enable the debug statements with the following command: ```bash $ DEBUG=sample-app:* node ./bin/www ``` You can specify more than one debug namespace by assigning a comma-separated list of names: ```bash $ DEBUG=http,mail,express:* node index.js ``` ## Advanced options When running through Node.js, you can set a few environment variables that will change the behavior of the debug logging: | Name | Purpose | |-----------|-------------------------------------------------| | `DEBUG` | Enables/disables specific debugging namespaces. | | `DEBUG_COLORS`| Whether or not to use colors in the debug output. | | `DEBUG_DEPTH` | Object inspection depth. | | `DEBUG_FD` | File descriptor to write debug output to. | | `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | {% capture debug-text %} The environment variables beginning with `DEBUG_` end up being converted into an Options object that gets used with `%o`/`%O` formatters. See the Node.js documentation for [`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) for the complete list. {% endcapture %} {% include admonitions/note.html content=debug-text %} --- --- layout: page title: Express error handling description: Understand how Express.js handles errors in synchronous and asynchronous code, and learn to implement custom error handling middleware for your applications. menu: guide order: 6 redirect_from: "/guide/error-handling.html" --- # Error Handling _Error Handling_ refers to how Express catches and processes errors that occur both synchronously and asynchronously. Express comes with a default error handler so you don't need to write your own to get started. ## Catching Errors It's important to ensure that Express catches all errors that occur while running route handlers and middleware. Errors that occur in synchronous code inside route handlers and middleware require no extra work. If synchronous code throws an error, then Express will catch and process it. For example: ```js app.get('/', (req, res) => { throw new Error('BROKEN') // Express will catch this on its own. }) ``` For errors returned from asynchronous functions invoked by route handlers and middleware, you must pass them to the `next()` function, where Express will catch and process them. For example: ```js app.get('/', (req, res, next) => { fs.readFile('/file-does-not-exist', (err, data) => { if (err) { next(err) // Pass errors to Express. } else { res.send(data) } }) }) ``` Starting with Express 5, route handlers and middleware that return a Promise will call `next(value)` automatically when they reject or throw an error. For example: ```js app.get('/user/:id', async (req, res, next) => { const user = await getUserById(req.params.id) res.send(user) }) ``` If `getUserById` throws an error or rejects, `next` will be called with either the thrown error or the rejected value. If no rejected value is provided, `next` will be called with a default Error object provided by the Express router. If you pass anything to the `next()` function (except the string `'route'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions. If the callback in a sequence provides no data, only errors, you can simplify this code as follows: ```js app.get('/', [ function (req, res, next) { fs.writeFile('/inaccessible-path', 'data', next) }, function (req, res) { res.send('OK') } ]) ``` In the above example, `next` is provided as the callback for `fs.writeFile`, which is called with or without errors. If there is no error, the second handler is executed, otherwise Express catches and processes the error. You must catch errors that occur in asynchronous code invoked by route handlers or middleware and pass them to Express for processing. For example: ```js app.get('/', (req, res, next) => { setTimeout(() => { try { throw new Error('BROKEN') } catch (err) { next(err) } }, 100) }) ``` The above example uses a `try...catch` block to catch errors in the asynchronous code and pass them to Express. If the `try...catch` block were omitted, Express would not catch the error since it is not part of the synchronous handler code. Use promises to avoid the overhead of the `try...catch` block or when using functions that return promises. For example: ```js app.get('/', (req, res, next) => { Promise.resolve().then(() => { throw new Error('BROKEN') }).catch(next) // Errors will be passed to Express. }) ``` Since promises automatically catch both synchronous errors and rejected promises, you can simply provide `next` as the final catch handler and Express will catch errors, because the catch handler is given the error as the first argument. You could also use a chain of handlers to rely on synchronous error catching, by reducing the asynchronous code to something trivial. For example: ```js app.get('/', [ function (req, res, next) { fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => { res.locals.data = data next(err) }) }, function (req, res) { res.locals.data = res.locals.data.split(',')[1] res.send(res.locals.data) } ]) ``` The above example has a couple of trivial statements from the `readFile` call. If `readFile` causes an error, then it passes the error to Express, otherwise you quickly return to the world of synchronous error handling in the next handler in the chain. Then, the example above tries to process the data. If this fails, then the synchronous error handler will catch it. If you had done this processing inside the `readFile` callback, then the application might exit and the Express error handlers would not run. Whichever method you use, if you want Express error handlers to be called in and the application to survive, you must ensure that Express receives the error. ## The default error handler Express comes with a built-in error handler that takes care of any errors that might be encountered in the app. This default error-handling middleware function is added at the end of the middleware function stack. If you pass an error to `next()` and you do not handle it in a custom error handler, it will be handled by the built-in error handler; the error will be written to the client with the stack trace. The stack trace is not included in the production environment.
Set the environment variable `NODE_ENV` to `production`, to run the app in production mode.
When an error is written, the following information is added to the response: * The `res.statusCode` is set from `err.status` (or `err.statusCode`). If this value is outside the 4xx or 5xx range, it will be set to 500. * The `res.statusMessage` is set according to the status code. * The body will be the HTML of the status code message when in production environment, otherwise will be `err.stack`. * Any headers specified in an `err.headers` object. If you call `next()` with an error after you have started writing the response (for example, if you encounter an error while streaming the response to the client), the Express default error handler closes the connection and fails the request. So when you add a custom error handler, you must delegate to the default Express error handler, when the headers have already been sent to the client: ```js function errorHandler (err, req, res, next) { if (res.headersSent) { return next(err) } res.status(500) res.render('error', { error: err }) } ``` Note that the default error handler can get triggered if you call `next()` with an error in your code more than once, even if custom error handling middleware is in place. Other error handling middleware can be found at [Express middleware](/{{ page.lang }}/resources/middleware.html). ## Writing error handlers Define error-handling middleware functions in the same way as other middleware functions, except error-handling functions have four arguments instead of three: `(err, req, res, next)`. For example: ```js app.use((err, req, res, next) => { console.error(err.stack) res.status(500).send('Something broke!') }) ``` You define error-handling middleware last, after other `app.use()` and routes calls; for example: ```js const bodyParser = require('body-parser') const methodOverride = require('method-override') app.use(bodyParser.urlencoded({ extended: true })) app.use(bodyParser.json()) app.use(methodOverride()) app.use((err, req, res, next) => { // logic }) ``` Responses from within a middleware function can be in any format, such as an HTML error page, a simple message, or a JSON string. For organizational (and higher-level framework) purposes, you can define several error-handling middleware functions, much as you would with regular middleware functions. For example, to define an error-handler for requests made by using `XHR` and those without: ```js const bodyParser = require('body-parser') const methodOverride = require('method-override') app.use(bodyParser.urlencoded({ extended: true })) app.use(bodyParser.json()) app.use(methodOverride()) app.use(logErrors) app.use(clientErrorHandler) app.use(errorHandler) ``` In this example, the generic `logErrors` might write request and error information to `stderr`, for example: ```js function logErrors (err, req, res, next) { console.error(err.stack) next(err) } ``` Also in this example, `clientErrorHandler` is defined as follows; in this case, the error is explicitly passed along to the next one. Notice that when _not_ calling "next" in an error-handling function, you are responsible for writing (and ending) the response. Otherwise, those requests will "hang" and will not be eligible for garbage collection. ```js function clientErrorHandler (err, req, res, next) { if (req.xhr) { res.status(500).send({ error: 'Something failed!' }) } else { next(err) } } ``` Implement the "catch-all" `errorHandler` function as follows (for example): ```js function errorHandler (err, req, res, next) { res.status(500) res.render('error', { error: err }) } ``` If you have a route handler with multiple callback functions, you can use the `route` parameter to skip to the next route handler. For example: ```js app.get('/a_route_behind_paywall', (req, res, next) => { if (!req.user.hasPaid) { // continue handling this request next('route') } else { next() } }, (req, res, next) => { PaidContent.find((err, doc) => { if (err) return next(err) res.json(doc) }) }) ``` In this example, the `getPaidContent` handler will be skipped but any remaining handlers in `app` for `/a_route_behind_paywall` would continue to be executed.
Calls to `next()` and `next(err)` indicate that the current handler is complete and in what state. `next(err)` will skip all remaining handlers in the chain except for those that are set up to handle errors as described above.
--- --- layout: page title: Migrating to Express 4 description: A guide to migrating your Express.js applications from version 3 to 4, covering changes in middleware, routing, and how to update your codebase effectively. menu: guide order: 9 redirect_from: "/guide/migrating-4.html" --- # Moving to Express 4

Overview

Express 4 is a breaking change from Express 3. That means an existing Express 3 app will _not_ work if you update the Express version in its dependencies. This article covers:

Changes in Express 4

There are several significant changes in Express 4: See also: * [New features in 4.x.](https://github.com/expressjs/express/wiki/New-features-in-4.x) * [Migrating from 3.x to 4.x.](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x)

Changes to Express core and middleware system

Express 4 no longer depends on Connect, and removes all built-in middleware from its core, except for the `express.static` function. This means that Express is now an independent routing and middleware web framework, and Express versioning and releases are not affected by middleware updates. Without built-in middleware, you must explicitly add all the middleware that is required to run your app. Simply follow these steps: 1. Install the module: `npm install --save ` 2. In your app, require the module: `require('module-name')` 3. Use the module according to its documentation: `app.use( ... )` The following table lists Express 3 middleware and their counterparts in Express 4.
Express 3Express 4
express.bodyParser body-parser + multer
express.compress compression
express.cookieSession cookie-session
express.cookieParser cookie-parser
express.logger morgan
express.session express-session
express.favicon serve-favicon
express.responseTime response-time
express.errorHandler errorhandler
express.methodOverride method-override
express.timeout connect-timeout
express.vhost vhost
express.csrf csurf
express.directory serve-index
express.static serve-static
Here is the [complete list](https://github.com/senchalabs/connect#middleware) of Express 4 middleware. In most cases, you can simply replace the old version 3 middleware with its Express 4 counterpart. For details, see the module documentation in GitHub.

app.use accepts parameters

In version 4 you can use a variable parameter to define the path where middleware functions are loaded, then read the value of the parameter from the route handler. For example: ```js app.use('/book/:id', (req, res, next) => { console.log('ID:', req.params.id) next() }) ```

The routing system

Apps now implicitly load routing middleware, so you no longer have to worry about the order in which middleware is loaded with respect to the `router` middleware. The way you define routes is unchanged, but the routing system has two new features to help organize your routes: {: .doclist } * A new method, `app.route()`, to create chainable route handlers for a route path. * A new class, `express.Router`, to create modular mountable route handlers.

app.route() method

The new `app.route()` method enables you to create chainable route handlers for a route path. Because the path is specified in a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see [`Router()` documentation](/{{ page.lang }}/4x/api.html#router). Here is an example of chained route handlers that are defined by using the `app.route()` function. ```js app.route('/book') .get((req, res) => { res.send('Get a random book') }) .post((req, res) => { res.send('Add a book') }) .put((req, res) => { res.send('Update the book') }) ```

express.Router class

The other feature that helps to organize routes is a new class, `express.Router`, that you can use to create modular mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason it is often referred to as a "mini-app". The following example creates a router as a module, loads middleware in it, defines some routes, and mounts it on a path on the main app. For example, create a router file named `birds.js` in the app directory, with the following content: ```js var express = require('express') var router = express.Router() // middleware specific to this router router.use((req, res, next) => { console.log('Time: ', Date.now()) next() }) // define the home page route router.get('/', (req, res) => { res.send('Birds home page') }) // define the about route router.get('/about', (req, res) => { res.send('About birds') }) module.exports = router ``` Then, load the router module in the app: ```js var birds = require('./birds') // ... app.use('/birds', birds) ``` The app will now be able to handle requests to the `/birds` and `/birds/about` paths, and will call the `timeLog` middleware that is specific to the route.

Other changes

The following table lists other small but important changes in Express 4:
Object Description
Node.js Express 4 requires Node.js 0.10.x or later and has dropped support for Node.js 0.8.x.
`http.createServer()` The `http` module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). The app can be started by using the `app.listen()` function.
`app.configure()` The `app.configure()` function has been removed. Use the `process.env.NODE_ENV` or `app.get('env')` function to detect the environment and configure the app accordingly.
`json spaces` The `json spaces` application property is disabled by default in Express 4.
`req.accepted()` Use `req.accepts()`, `req.acceptsEncodings()`, `req.acceptsCharsets()`, and `req.acceptsLanguages()`.
`res.location()` No longer resolves relative URLs.
`req.params` Was an array; now an object.
`res.locals` Was a function; now an object.
`res.headerSent` Changed to `res.headersSent`.
`app.route` Now available as `app.mountpath`.
`res.on('header')` Removed.
`res.charset` Removed.
`res.setHeader('Set-Cookie', val)` Functionality is now limited to setting the basic cookie value. Use `res.cookie()` for added functionality.

Example app migration

Here is an example of migrating an Express 3 application to Express 4. The files of interest are `app.js` and `package.json`.

Version 3 app

app.js

Consider an Express v.3 application with the following `app.js` file: ```js var express = require('express') var routes = require('./routes') var user = require('./routes/user') var http = require('http') var path = require('path') var app = express() // all environments app.set('port', process.env.PORT || 3000) app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'pug') app.use(express.favicon()) app.use(express.logger('dev')) app.use(express.methodOverride()) app.use(express.session({ secret: 'your secret here' })) app.use(express.bodyParser()) app.use(app.router) app.use(express.static(path.join(__dirname, 'public'))) // development only if (app.get('env') === 'development') { app.use(express.errorHandler()) } app.get('/', routes.index) app.get('/users', user.list) http.createServer(app).listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) }) ```

package.json

The accompanying version 3 `package.json` file might look something like this: ```json { "name": "application-name", "version": "0.0.1", "private": true, "scripts": { "start": "node app.js" }, "dependencies": { "express": "3.12.0", "pug": "*" } } ```

Process

Begin the migration process by installing the required middleware for the Express 4 app and updating Express and Pug to their respective latest version with the following command: ```bash $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save ``` Make the following changes to `app.js`: 1. The built-in Express middleware functions `express.favicon`, `express.logger`, `express.methodOverride`, `express.session`, `express.bodyParser` and `express.errorHandler` are no longer available on the `express` object. You must install their alternatives manually and load them in the app. 2. You no longer need to load the `app.router` function. It is not a valid Express 4 app object, so remove the `app.use(app.router);` code. 3. Make sure that the middleware functions are loaded in the correct order - load `errorHandler` after loading the app routes.

Version 4 app

package.json

Running the above `npm` command will update `package.json` as follows: ```json { "name": "application-name", "version": "0.0.1", "private": true, "scripts": { "start": "node app.js" }, "dependencies": { "body-parser": "^1.5.2", "errorhandler": "^1.1.1", "express": "^4.8.0", "express-session": "^1.7.2", "pug": "^2.0.0", "method-override": "^2.1.2", "morgan": "^1.2.2", "multer": "^0.1.3", "serve-favicon": "^2.0.1" } } ```

app.js

Then, remove invalid code, load the required middleware, and make other changes as necessary. The `app.js` file will look like this: ```js var http = require('http') var express = require('express') var routes = require('./routes') var user = require('./routes/user') var path = require('path') var favicon = require('serve-favicon') var logger = require('morgan') var methodOverride = require('method-override') var session = require('express-session') var bodyParser = require('body-parser') var multer = require('multer') var errorHandler = require('errorhandler') var app = express() // all environments app.set('port', process.env.PORT || 3000) app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'pug') app.use(favicon(path.join(__dirname, '/public/favicon.ico'))) app.use(logger('dev')) app.use(methodOverride()) app.use(session({ resave: true, saveUninitialized: true, secret: 'uwotm8' })) app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: true })) app.use(multer()) app.use(express.static(path.join(__dirname, 'public'))) app.get('/', routes.index) app.get('/users', user.list) // error handling middleware should be loaded after the loading the routes if (app.get('env') === 'development') { app.use(errorHandler()) } var server = http.createServer(app) server.listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) }) ```
Unless you need to work directly with the `http` module (socket.io/SPDY/HTTPS), loading it is not required, and the app can be simply started this way: ```js app.listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) }) ```

Run the app

The migration process is complete, and the app is now an Express 4 app. To confirm, start the app by using the following command: ```bash $ node . ``` Load [http://localhost:3000](http://localhost:3000) and see the home page being rendered by Express 4.

Upgrading to the Express 4 app generator

The command-line tool to generate an Express app is still `express`, but to upgrade to the new version, you must uninstall the Express 3 app generator and then install the new `express-generator`.

Installing

If you already have the Express 3 app generator installed on your system, you must uninstall it: ```bash $ npm uninstall -g express ``` Depending on how your file and directory privileges are configured, you might need to run this command with `sudo`. Now install the new generator: ```bash $ npm install -g express-generator ``` Depending on how your file and directory privileges are configured, you might need to run this command with `sudo`. Now the `express` command on your system is updated to the Express 4 generator.

Changes to the app generator

Command options and use largely remain the same, with the following exceptions: {: .doclist } * Removed the `--sessions` option. * Removed the `--jshtml` option. * Added the `--hogan` option to support [Hogan.js](http://twitter.github.io/hogan.js/).

Example

Execute the following command to create an Express 4 app: ```bash $ express app4 ``` If you look at the contents of the `app4/app.js` file, you will notice that all the middleware functions (except `express.static`) that are required for the app are loaded as independent modules, and the `router` middleware is no longer explicitly loaded in the app. You will also notice that the `app.js` file is now a Node.js module, in contrast to the standalone app that was generated by the old generator. After installing the dependencies, start the app by using the following command: ```bash $ npm start ``` If you look at the `npm start` script in the `package.json` file, you will notice that the actual command that starts the app is `node ./bin/www`, which used to be `node app.js` in Express 3. Because the `app.js` file that was generated by the Express 4 generator is now a Node.js module, it can no longer be started independently as an app (unless you modify the code). The module must be loaded in a Node.js file and started via the Node.js file. The Node.js file is `./bin/www` in this case. Neither the `bin` directory nor the extensionless `www` file is mandatory for creating an Express app or starting the app. They are just suggestions made by the generator, so feel free to modify them to suit your needs. To get rid of the `www` directory and keep things the "Express 3 way", delete the line that says `module.exports = app;` at the end of the `app.js` file, then paste the following code in its place: ```js app.set('port', process.env.PORT || 3000) var server = app.listen(app.get('port'), () => { debug('Express server listening on port ' + server.address().port) }) ``` Ensure that you load the `debug` module at the top of the `app.js` file by using the following code: ```js var debug = require('debug')('app4') ``` Next, change `"start": "node ./bin/www"` in the `package.json` file to `"start": "node app.js"`. You have now moved the functionality of `./bin/www` back to `app.js`. This change is not recommended, but the exercise helps you to understand how the `./bin/www` file works, and why the `app.js` file no longer starts on its own. --- --- layout: page title: Migrating to Express 5 description: A comprehensive guide to migrating your Express.js applications from version 4 to 5, detailing breaking changes, deprecated methods, and new improvements. menu: guide order: 10 redirect_from: "/guide/migrating-5.html" --- # Moving to Express 5

Overview

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: ```sh npm install "express@5" ``` 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. ## Express 5 Codemods To help you migrate your express server, we have created a set of codemods that will help you automatically update your code to the latest version of Express. Run the following command for run all the codemods available: ```sh npx @expressjs/codemod upgrade ``` If you want to run a specific codemod, you can run the following command: ```sh npx @expressjs/codemod name-of-the-codemod ``` You can find the list of available codemods [here](https://github.com/expressjs/codemod?tab=readme-ov-file#available-codemods).

Changes in Express 5

**Removed methods and properties** **Changed** **Improvements** ## Removed methods and properties 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.

app.del()

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. {% capture codemod-deprecated-signatures %} You can replace the deprecated signatures with the following command: ```plain-text npx @expressjs/codemod v4-deprecated-signatures ``` {% endcapture %} {% include admonitions/note.html content=codemod-deprecated-signatures %} ```js // v4 app.del('/user/:id', (req, res) => { res.send(`DELETE /user/${req.params.id}`) }) // v5 app.delete('/user/:id', (req, res) => { res.send(`DELETE /user/${req.params.id}`) }) ```

app.param(fn)

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.

Pluralized method names

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()`. {% capture codemod-pluralized-methods %} You can replace the deprecated signatures with the following command: ```plain-text npx @expressjs/codemod pluralized-methods ``` {% endcapture %} {% include admonitions/note.html content=codemod-pluralized-methods %} ```js // v4 app.all('/', (req, res) => { req.acceptsCharset('utf-8') req.acceptsEncoding('br') req.acceptsLanguage('en') // ... }) // v5 app.all('/', (req, res) => { req.acceptsCharsets('utf-8') req.acceptsEncodings('br') req.acceptsLanguages('en') // ... }) ```

Leading colon (:) in the name for app.param(name, fn)

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](/{{ page.lang }}/4x/api.html#app.param), as it makes no mention of the leading colon.

req.param(name)

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. {% capture codemod-req-param %} You can replace the deprecated signatures with the following command: ```plain-text npx @expressjs/codemod req-param ``` {% endcapture %} {% include admonitions/note.html content=codemod-req-param %} ```js // v4 app.post('/user', (req, res) => { const id = req.param('id') const body = req.param('body') const query = req.param('query') // ... }) // v5 app.post('/user', (req, res) => { const id = req.params.id const body = req.body const query = req.query // ... }) ```

res.json(obj, status)

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)`. {% include admonitions/note.html content=codemod-deprecated-signatures %} ```js // v4 app.post('/user', (req, res) => { res.json({ name: 'Ruben' }, 201) }) // v5 app.post('/user', (req, res) => { res.status(201).json({ name: 'Ruben' }) }) ```

res.jsonp(obj, status)

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)`. {% include admonitions/note.html content=codemod-deprecated-signatures %} ```js // v4 app.post('/user', (req, res) => { res.jsonp({ name: 'Ruben' }, 201) }) // v5 app.post('/user', (req, res) => { res.status(201).jsonp({ name: 'Ruben' }) }) ```

res.redirect(url, status)

Express 5 no longer supports the signature `res.redirect(url, status)`. Instead, use the following signature: `res.redirect(status, url)`. {% include admonitions/note.html content=codemod-deprecated-signatures %} ```js // v4 app.get('/user', (req, res) => { res.redirect('/users', 301) }) // v5 app.get('/user', (req, res) => { res.redirect(301, '/users') }) ```

res.redirect('back') and res.location('back')

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. {% capture codemod-magic-redirect %} You can replace the deprecated signatures with the following command: ```plain-text npx @expressjs/codemod magic-redirect ``` {% endcapture %} {% include admonitions/note.html content=codemod-magic-redirect %} ```js // v4 app.get('/user', (req, res) => { res.redirect('back') }) // v5 app.get('/user', (req, res) => { res.redirect(req.get('Referrer') || '/') }) ```

res.send(body, status)

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)`. {% include admonitions/note.html content=codemod-deprecated-signatures %} ```js // v4 app.get('/user', (req, res) => { res.send({ name: 'Ruben' }, 200) }) // v5 app.get('/user', (req, res) => { res.status(200).send({ name: 'Ruben' }) }) ```

res.send(status)

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. {% include admonitions/note.html content=codemod-deprecated-signatures %} ```js // v4 app.get('/user', (req, res) => { res.send(200) }) // v5 app.get('/user', (req, res) => { res.sendStatus(200) }) ```

res.sendfile()

The `res.sendfile()` function has been replaced by a camel-cased version `res.sendFile()` in Express 5. **Note:** In Express 5, `res.sendFile()` uses the `mime-types` package for MIME type detection, which returns different Content-Type values than Express 4 for several common file types: - JavaScript files (.js): now "text/javascript" instead of "application/javascript" - JSON files (.json): now "application/json" instead of "text/json" - CSS files (.css): now "text/css" instead of "text/plain" - XML files (.xml): now "application/xml" instead of "text/xml" - Font files (.woff): now "font/woff" instead of "application/font-woff" - SVG files (.svg): now "image/svg+xml" instead of "application/svg+xml" {% include admonitions/note.html content=codemod-deprecated-signatures %} ```js // v4 app.get('/user', (req, res) => { res.sendfile('/path/to/file') }) // v5 app.get('/user', (req, res) => { res.sendFile('/path/to/file') }) ```

router.param(fn)

The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all.

express.static.mime

In Express 5, `mime` is no longer an exported property of the `static` field. Use the [`mime-types` package](https://github.com/jshttp/mime-types) to work with MIME type values. **Important:** This change affects not only direct usage of `express.static.mime` but also other Express methods that rely on MIME type detection, such as `res.sendFile()`. The following MIME types have changed from Express 4: - JavaScript files (.js): now served as "text/javascript" instead of "application/javascript" - JSON files (.json): now served as "application/json" instead of "text/json" - CSS files (.css): now served as "text/css" instead of "text/plain" - HTML files (.html): now served as "text/html; charset=utf-8" instead of just "text/html" - XML files (.xml): now served as "application/xml" instead of "text/xml" - Font files (.woff): now served as "font/woff" instead of "application/font-woff" ```js // v4 express.static.mime.lookup('json') // v5 const mime = require('mime-types') mime.lookup('json') ```

express:router debug logs

In Express 5, router handling logic is performed by a dependency. Therefore, the debug logs for the router are no longer available under the `express:` namespace. In v4, the logs were available under the namespaces `express:router`, `express:router:layer`, and `express:router:route`. All of these were included under the namespace `express:*`. In v5.1+, the logs are available under the namespaces `router`, `router:layer`, and `router:route`. The logs from `router:layer` and `router:route` are included in the namespace `router:*`. To achieve the same detail of debug logging when using `express:*` in v4, use a conjunction of `express:*`, `router`, and `router:*`. ```sh # v4 DEBUG=express:* node index.js # v5 DEBUG=express:*,router,router:* node index.js ``` ## Changed

Path route matching syntax

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: - The wildcard `*` must have a name, matching the behavior of parameters `:`, use `/*splat` instead of `/*` ```js // v4 app.get('/*', async (req, res) => { res.send('ok') }) // v5 app.get('/*splat', async (req, res) => { res.send('ok') }) ``` {% capture note_wildcard %} `*splat` matches any path without the root path. If you need to match the root path as well `/`, you can use `/{*splat}`, wrapping the wildcard in braces. ```js // v5 app.get('/{*splat}', async (req, res) => { res.send('ok') }) ``` {% endcapture %} {% include admonitions/note.html content=note_wildcard %} - The optional character `?` is no longer supported, use braces instead. ```js // v4 app.get('/:file.:ext?', async (req, res) => { res.send('ok') }) // v5 app.get('/:file{.:ext}', async (req, res) => { res.send('ok') }) ``` - Regexp characters are not supported. For example: ```js app.get('/[discussion|page]/:slug', async (req, res) => { res.status(200).send('ok') }) ``` should be changed to: ```js app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => { res.status(200).send('ok') }) ``` - Some characters have been reserved to avoid confusion during upgrade (`()[]?+!`), use `\` to escape them. - Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`.

Rejected promises handled from middleware and handlers

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](/en/guide/error-handling.html).

express.urlencoded

The `express.urlencoded` method makes the `extended` option `false` by default.

express.static dotfiles

In Express 5, the `express.static` middleware's `dotfiles` option now defaults to `"ignore"`. This is a change from Express 4, where dotfiles were served by default. As a result, files inside a directory that starts with a dot (`.`), such as `.well-known`, will no longer be accessible and will return a **404 Not Found** error. This can break functionality that depends on serving dot-directories, such as Android App Links, and Apple Universal Links. Example of breaking code: ```js // v4 app.use(express.static('public')) ``` After migrating to Express 5, a request to `/.well-known/assetlinks.json` will result in a **404 Not Found**. To fix this, serve specific dot-directories explicitly using the `dotfiles: "allow"` option: ```js // v5 app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' })) app.use(express.static('public')) ``` This approach allows you to safely serve only the intended dot-directories while keeping the default secure behavior for other dotfiles, which remain inaccessible.

app.listen

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: ```js 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())}`) }) ```

app.router

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.

req.body

The `req.body` property returns `undefined` when the body has not been parsed. In Express 4, it returns `{}` by default.

req.host

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.

req.params

The `req.params` object now has a **null prototype** when using string paths. However, if the path is defined with a regular expression, `req.params` remains a standard object with a normal prototype. Additionally, there are two important behavioral changes: **Wildcard parameters are now arrays:** Wildcards (e.g., `/*splat`) capture path segments as an array instead of a single string. ```js app.get('/*splat', (req, res) => { // GET /foo/bar console.dir(req.params) // => [Object: null prototype] { splat: [ 'foo', 'bar' ] } }) ``` **Unmatched parameters are omitted:** In Express 4, unmatched wildcards were empty strings (`''`) and optional `:` parameters (using `?`) had a key with value `undefined`. In Express 5, unmatched parameters are completely omitted from `req.params`. ```js // v4: unmatched wildcard is empty string app.get('/*', (req, res) => { // GET / console.dir(req.params) // => { '0': '' } }) // v4: unmatched optional param is undefined app.get('/:file.:ext?', (req, res) => { // GET /image console.dir(req.params) // => { file: 'image', ext: undefined } }) // v5: unmatched optional param is omitted app.get('/:file{.:ext}', (req, res) => { // GET /image console.dir(req.params) // => [Object: null prototype] { file: 'image' } }) ```

req.query

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".

res.clearCookie

The `res.clearCookie` method ignores the `maxAge` and `expires` options provided by the user.

res.status

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.

res.vary

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 ## Improvements

res.render()

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.

Brotli encoding support

Express 5 supports Brotli encoding for requests received from clients that support it. --- --- layout: page title: Overriding the Express API description: Discover how to customize and extend the Express.js API by overriding methods and properties on the request and response objects using prototypes. menu: guide order: 4 --- # Overriding the Express API The Express API consists of various methods and properties on the request and response objects. These are inherited by prototype. There are two extension points for the Express API: 1. The global prototypes at `express.request` and `express.response`. 2. App-specific prototypes at `app.request` and `app.response`. Altering the global prototypes will affect all loaded Express apps in the same process. If desired, alterations can be made app-specific by only altering the app-specific prototypes after creating a new app. ## Methods You can override the signature and behavior of existing methods with your own, by assigning a custom function. Following is an example of overriding the behavior of [res.sendStatus](/4x/api.html#res.sendStatus). ```js app.response.sendStatus = function (statusCode, type, message) { // code is intentionally kept simple for demonstration purpose return this.contentType(type) .status(statusCode) .send(message) } ``` The above implementation completely changes the original signature of `res.sendStatus`. It now accepts a status code, encoding type, and the message to be sent to the client. The overridden method may now be used this way: ```js res.sendStatus(404, 'application/json', '{"error":"resource not found"}') ``` ## Properties Properties in the Express API are either: 1. Assigned properties (ex: `req.baseUrl`, `req.originalUrl`) 2. Defined as getters (ex: `req.secure`, `req.ip`) Since properties under category 1 are dynamically assigned on the `request` and `response` objects in the context of the current request-response cycle, their behavior cannot be overridden. Properties under category 2 can be overwritten using the Express API extensions API. The following code rewrites how the value of `req.ip` is to be derived. Now, it simply returns the value of the `Client-IP` request header. ```js Object.defineProperty(app.request, 'ip', { configurable: true, enumerable: true, get () { return this.get('Client-IP') } }) ``` ## Prototype In order to provide the Express API, the request/response objects passed to Express (via `app(req, res)`, for example) need to inherit from the same prototype chain. By default, this is `http.IncomingRequest.prototype` for the request and `http.ServerResponse.prototype` for the response. Unless necessary, it is recommended that this be done only at the application level, rather than globally. Also, take care that the prototype that is being used matches the functionality as closely as possible to the default prototypes. ```js // Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse // for the given app reference Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype) Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype) ``` --- --- layout: page title: Express routing description: Learn how to define and use routes in Express.js applications, including route methods, route paths, parameters, and using Router for modular routing. menu: guide order: 1 redirect_from: "/guide/routing.html" --- # Routing _Routing_ refers to how an application's endpoints (URIs) respond to client requests. For an introduction to routing, see [Basic routing](/{{ page.lang }}/starter/basic-routing.html). You define routing using methods of the Express `app` object that correspond to HTTP methods; for example, `app.get()` to handle GET requests and `app.post` to handle POST requests. For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). You can also use [app.all()](/{{ page.lang }}/5x/api.html#app.all) to handle all HTTP methods and [app.use()](/{{ page.lang }}/5x/api.html#app.use) to specify middleware as the callback function (See [Using middleware](/{{ page.lang }}/guide/using-middleware.html) for details). These routing methods specify a callback function (sometimes called "handler functions") called when the application receives a request to the specified route (endpoint) and HTTP method. In other words, the application "listens" for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function. In fact, the routing methods can have more than one callback function as arguments. With multiple callback functions, it is important to provide `next` as an argument to the callback function and then call `next()` within the body of the function to hand off control to the next callback. The following code is an example of a very basic route. ```js const express = require('express') const app = express() // respond with "hello world" when a GET request is made to the homepage app.get('/', (req, res) => { res.send('hello world') }) ```

Route methods

A route method is derived from one of the HTTP methods, and is attached to an instance of the `express` class. The following code is an example of routes that are defined for the `GET` and the `POST` methods to the root of the app. ```js // GET method route app.get('/', (req, res) => { res.send('GET request to the homepage') }) // POST method route app.post('/', (req, res) => { res.send('POST request to the homepage') }) ``` Express supports methods that correspond to all HTTP request methods: `get`, `post`, and so on. For a full list, see [app.METHOD](/{{ page.lang }}/5x/api.html#app.METHOD). There is a special routing method, `app.all()`, used to load middleware functions at a path for _all_ HTTP request methods. For example, the following handler is executed for requests to the route `"/secret"` whether using `GET`, `POST`, `PUT`, `DELETE`, or any other HTTP request method supported in the [http module](https://nodejs.org/api/http.html#http_http_methods). ```js app.all('/secret', (req, res, next) => { console.log('Accessing the secret section ...') next() // pass control to the next handler }) ```

Route paths

Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions. {% capture caution-character %} In express 5, the characters `?`, `+`, `*`, `[]`, and `()` are handled differently than in version 4, please review the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} {% include admonitions/caution.html content=caution-character %} {% capture note-dollar-character %}In express 4, regular expression characters such as `$` need to be escaped with a `\`. {% endcapture %} {% include admonitions/caution.html content=note-dollar-character %} {% capture note-path-to-regexp %} Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths. [Express Playground Router](https://bjohansebas.github.io/playground-router/) is a handy tool for testing basic Express routes, although it does not support pattern matching. {% endcapture %} {% include admonitions/note.html content=note-path-to-regexp %} {% capture query-string-note %} Query strings are not part of the route path. {% endcapture %} {% include admonitions/warning.html content=query-string-note %} ### Route paths based on strings This route path will match requests to the root route, `/`. ```js app.get('/', (req, res) => { res.send('root') }) ``` This route path will match requests to `/about`. ```js app.get('/about', (req, res) => { res.send('about') }) ``` This route path will match requests to `/random.text`. ```js app.get('/random.text', (req, res) => { res.send('random.text') }) ``` ### Route paths based on string patterns {% capture caution-string-patterns %} The string patterns in Express 5 no longer work. Please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax) for more information.{% endcapture %} {% include admonitions/caution.html content=caution-string-patterns %} This route path will match `acd` and `abcd`. ```js app.get('/ab?cd', (req, res) => { res.send('ab?cd') }) ``` This route path will match `abcd`, `abbcd`, `abbbcd`, and so on. ```js app.get('/ab+cd', (req, res) => { res.send('ab+cd') }) ``` This route path will match `abcd`, `abxcd`, `abRANDOMcd`, `ab123cd`, and so on. ```js app.get('/ab*cd', (req, res) => { res.send('ab*cd') }) ``` This route path will match `/abe` and `/abcde`. ```js app.get('/ab(cd)?e', (req, res) => { res.send('ab(cd)?e') }) ``` ### Route paths based on regular expressions This route path will match anything with an "a" in it. ```js app.get(/a/, (req, res) => { res.send('/a/') }) ``` This route path will match `butterfly` and `dragonfly`, but not `butterflyman`, `dragonflyman`, and so on. ```js app.get(/.*fly$/, (req, res) => { res.send('/.*fly$/') }) ```

Route parameters

Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter specified in the path as their respective keys. ``` Route path: /users/:userId/books/:bookId Request URL: http://localhost:3000/users/34/books/8989 req.params: { "userId": "34", "bookId": "8989" } ``` To define routes with route parameters, simply specify the route parameters in the path of the route as shown below. ```js app.get('/users/:userId/books/:bookId', (req, res) => { res.send(req.params) }) ```
The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]).
Since the hyphen (`-`) and the dot (`.`) are interpreted literally, they can be used along with route parameters for useful purposes. ``` Route path: /flights/:from-:to Request URL: http://localhost:3000/flights/LAX-SFO req.params: { "from": "LAX", "to": "SFO" } ``` ``` Route path: /plantae/:genus.:species Request URL: http://localhost:3000/plantae/Prunus.persica req.params: { "genus": "Prunus", "species": "persica" } ``` {% capture warning-regexp %} In express 5, Regexp characters are not supported in route paths, for more information please refer to the [migration guide](/{{ page.lang }}/guide/migrating-5.html#path-syntax).{% endcapture %} {% include admonitions/caution.html content=warning-regexp %} To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (`()`): ``` Route path: /user/:userId(\d+) Request URL: http://localhost:3000/user/42 req.params: {"userId": "42"} ``` {% capture escape-advisory %} Because the regular expression is usually part of a literal string, be sure to escape any `\` characters with an additional backslash, for example `\\d+`. {% endcapture %} {% include admonitions/warning.html content=escape-advisory %} {% capture warning-version %} In Express 4.x, the `*` character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`. This will likely be fixed in Express 5. {% endcapture %} {% include admonitions/warning.html content=warning-version %}

Route handlers

You can provide multiple callback functions that behave like [middleware](/{{ page.lang }}/guide/using-middleware.html) to handle a request. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route. ```js app.get('/user/:id', (req, res, next) => { if (req.params.id === '0') { return next('route') } res.send(`User ${req.params.id}`) }) app.get('/user/:id', (req, res) => { res.send('Special handler for user ID 0') }) ``` In this example: - `GET /user/5` → handled by first route → sends "User 5" - `GET /user/0` → first route calls `next('route')`, skipping to the next matching `/user/:id` route Route handlers can be in the form of a function, an array of functions, or combinations of both, as shown in the following examples. A single callback function can handle a route. For example: ```js app.get('/example/a', (req, res) => { res.send('Hello from A!') }) ``` More than one callback function can handle a route (make sure you specify the `next` object). For example: ```js app.get('/example/b', (req, res, next) => { console.log('the response will be sent by the next function ...') next() }, (req, res) => { res.send('Hello from B!') }) ``` An array of callback functions can handle a route. For example: ```js const cb0 = function (req, res, next) { console.log('CB0') next() } const cb1 = function (req, res, next) { console.log('CB1') next() } const cb2 = function (req, res) { res.send('Hello from C!') } app.get('/example/c', [cb0, cb1, cb2]) ``` A combination of independent functions and arrays of functions can handle a route. For example: ```js const cb0 = function (req, res, next) { console.log('CB0') next() } const cb1 = function (req, res, next) { console.log('CB1') next() } app.get('/example/d', [cb0, cb1], (req, res, next) => { console.log('the response will be sent by the next function ...') next() }, (req, res) => { res.send('Hello from D!') }) ```

Response methods

The methods on the response object (`res`) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging. | Method | Description | | --------------------------------------------------------------- | ------------------------------------------------------------------------------------- | | [res.download()](/{{ page.lang }}/5x/api.html#res.download) | Prompt a file to be downloaded. | | [res.end()](/{{ page.lang }}/5x/api.html#res.end) | End the response process. | | [res.json()](/{{ page.lang }}/5x/api.html#res.json) | Send a JSON response. | | [res.jsonp()](/{{ page.lang }}/5x/api.html#res.jsonp) | Send a JSON response with JSONP support. | | [res.redirect()](/{{ page.lang }}/5x/api.html#res.redirect) | Redirect a request. | | [res.render()](/{{ page.lang }}/5x/api.html#res.render) | Render a view template. | | [res.send()](/{{ page.lang }}/5x/api.html#res.send) | Send a response of various types. | | [res.sendFile()](/{{ page.lang }}/5x/api.html#res.sendFile) | Send a file as an octet stream. | | [res.sendStatus()](/{{ page.lang }}/5x/api.html#res.sendStatus) | Set the response status code and send its string representation as the response body. |

app.route()

You can create chainable route handlers for a route path by using `app.route()`. Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/{{ page.lang }}/5x/api.html#router). Here is an example of chained route handlers that are defined by using `app.route()`. ```js app.route('/book') .get((req, res) => { res.send('Get a random book') }) .post((req, res) => { res.send('Add a book') }) .put((req, res) => { res.send('Update the book') }) ```

express.Router

Use the `express.Router` class to create modular, mountable route handlers. A `Router` instance is a complete middleware and routing system; for this reason, it is often referred to as a "mini-app". The following example creates a router as a module, loads a middleware function in it, defines some routes, and mounts the router module on a path in the main app. Create a router file named `birds.js` in the app directory, with the following content: ```js const express = require('express') const router = express.Router() // middleware that is specific to this router const timeLog = (req, res, next) => { console.log('Time: ', Date.now()) next() } router.use(timeLog) // define the home page route router.get('/', (req, res) => { res.send('Birds home page') }) // define the about route router.get('/about', (req, res) => { res.send('About birds') }) module.exports = router ``` Then, load the router module in the app: ```js const birds = require('./birds') // ... app.use('/birds', birds) ``` The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route. But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/{{ page.lang }}/5x/api.html#app.use). ```js const router = express.Router({ mergeParams: true }) ``` --- --- layout: page title: Using Express middleware description: Learn how to use middleware in Express.js applications, including application-level and router-level middleware, error handling, and integrating third-party middleware. menu: guide order: 3 redirect_from: "/guide/using-middleware.html" --- # Using middleware Express is a routing and middleware web framework that has minimal functionality of its own: An Express application is essentially a series of middleware function calls. _Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#res) (`res`), and the next middleware function in the application's request-response cycle. The next middleware function is commonly denoted by a variable named `next`. Middleware functions can perform the following tasks: * Execute any code. * Make changes to the request and the response objects. * End the request-response cycle. * Call the next middleware function in the stack. If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging. An Express application can use the following types of middleware: - [Application-level middleware](#middleware.application) - [Router-level middleware](#middleware.router) - [Error-handling middleware](#middleware.error-handling) - [Built-in middleware](#middleware.built-in) - [Third-party middleware](#middleware.third-party) You can load application-level and router-level middleware with an optional mount path. You can also load a series of middleware functions together, which creates a sub-stack of the middleware system at a mount point.

Application-level middleware

Bind application-level middleware to an instance of the [app object](/{{ page.lang }}/5x/api.html#app) by using the `app.use()` and `app.METHOD()` functions, where `METHOD` is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase. This example shows a middleware function with no mount path. The function is executed every time the app receives a request. ```js const express = require('express') const app = express() app.use((req, res, next) => { console.log('Time:', Date.now()) next() }) ``` This example shows a middleware function mounted on the `/user/:id` path. The function is executed for any type of HTTP request on the `/user/:id` path. ```js app.use('/user/:id', (req, res, next) => { console.log('Request Type:', req.method) next() }) ``` This example shows a route and its handler function (middleware system). The function handles GET requests to the `/user/:id` path. ```js app.get('/user/:id', (req, res, next) => { res.send('USER') }) ``` Here is an example of loading a series of middleware functions at a mount point, with a mount path. It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the `/user/:id` path. ```js app.use('/user/:id', (req, res, next) => { console.log('Request URL:', req.originalUrl) next() }, (req, res, next) => { console.log('Request Type:', req.method) next() }) ``` Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the `/user/:id` path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle. This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. ```js app.get('/user/:id', (req, res, next) => { console.log('ID:', req.params.id) next() }, (req, res, next) => { res.send('User Info') }) // handler for the /user/:id path, which prints the user ID app.get('/user/:id', (req, res, next) => { res.send(req.params.id) }) ``` To skip the rest of the middleware functions from a router middleware stack, call `next('route')` to pass control to the next route. {% capture next-function %} `next('route')` will work only in middleware functions that were loaded by using the `app.METHOD()` or `router.METHOD()` functions. {% endcapture %} {% include admonitions/note.html content=next-function %} This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. ```js app.get('/user/:id', (req, res, next) => { // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route') // otherwise pass the control to the next middleware function in this stack else next() }, (req, res, next) => { // send a regular response res.send('regular') }) // handler for the /user/:id path, which sends a special response app.get('/user/:id', (req, res, next) => { res.send('special') }) ``` Middleware can also be declared in an array for reusability. This example shows an array with a middleware sub-stack that handles GET requests to the `/user/:id` path ```js function logOriginalUrl (req, res, next) { console.log('Request URL:', req.originalUrl) next() } function logMethod (req, res, next) { console.log('Request Type:', req.method) next() } const logStuff = [logOriginalUrl, logMethod] app.get('/user/:id', logStuff, (req, res, next) => { res.send('User Info') }) ```

Router-level middleware

Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of `express.Router()`. ```js const router = express.Router() ``` Load router-level middleware by using the `router.use()` and `router.METHOD()` functions. The following example code replicates the middleware system that is shown above for application-level middleware, by using router-level middleware: ```js const express = require('express') const app = express() const router = express.Router() // a middleware function with no mount path. This code is executed for every request to the router router.use((req, res, next) => { console.log('Time:', Date.now()) next() }) // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path router.use('/user/:id', (req, res, next) => { console.log('Request URL:', req.originalUrl) next() }, (req, res, next) => { console.log('Request Type:', req.method) next() }) // a middleware sub-stack that handles GET requests to the /user/:id path router.get('/user/:id', (req, res, next) => { // if the user ID is 0, skip to the next router if (req.params.id === '0') next('route') // otherwise pass control to the next middleware function in this stack else next() }, (req, res, next) => { // render a regular page res.render('regular') }) // handler for the /user/:id path, which renders a special page router.get('/user/:id', (req, res, next) => { console.log(req.params.id) res.render('special') }) // mount the router on the app app.use('/', router) ``` To skip the rest of the router's middleware functions, call `next('router')` to pass control back out of the router instance. This example shows a middleware sub-stack that handles GET requests to the `/user/:id` path. ```js const express = require('express') const app = express() const router = express.Router() // predicate the router with a check and bail out when needed router.use((req, res, next) => { if (!req.headers['x-auth']) return next('router') next() }) router.get('/user/:id', (req, res) => { res.send('hello, user!') }) // use the router and 401 anything falling through app.use('/admin', router, (req, res) => { res.sendStatus(401) }) ```

Error-handling middleware

Error-handling middleware always takes _four_ arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don't need to use the `next` object, you must specify it to maintain the signature. Otherwise, the `next` object will be interpreted as regular middleware and will fail to handle errors.
Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature `(err, req, res, next)`: ```js app.use((err, req, res, next) => { console.error(err.stack) res.status(500).send('Something broke!') }) ``` For details about error-handling middleware, see: [Error handling](/{{ page.lang }}/guide/error-handling.html).

Built-in middleware

Starting with version 4.x, Express no longer depends on [Connect](https://github.com/senchalabs/connect). The middleware functions that were previously included with Express are now in separate modules; see [the list of middleware functions](https://github.com/senchalabs/connect#middleware). Express has the following built-in middleware functions: - [express.static](/en/5x/api.html#express.static) serves static assets such as HTML files, images, and so on. - [express.json](/en/5x/api.html#express.json) parses incoming requests with JSON payloads. **NOTE: Available with Express 4.16.0+** - [express.urlencoded](/en/5x/api.html#express.urlencoded) parses incoming requests with URL-encoded payloads. **NOTE: Available with Express 4.16.0+**

Third-party middleware

Use third-party middleware to add functionality to Express apps. Install the Node.js module for the required functionality, then load it in your app at the application level or at the router level. The following example illustrates installing and loading the cookie-parsing middleware function `cookie-parser`. ```bash $ npm install cookie-parser ``` ```js const express = require('express') const app = express() const cookieParser = require('cookie-parser') // load the cookie-parsing middleware app.use(cookieParser()) ``` For a partial list of third-party middleware functions that are commonly used with Express, see: [Third-party middleware](../resources/middleware.html). --- --- layout: page title: Using template engines with Express description: Discover how to integrate and use template engines like Pug, Handlebars, and EJS with Express.js to render dynamic HTML pages efficiently. menu: guide order: 5 redirect_from: "/guide/using-template-engines.html" --- # Using template engines with Express A _template engine_ enables you to use static template files in your application. At runtime, the template engine replaces variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page. The [Express application generator](/{{ page.lang }}/starter/generator.html) uses [Pug](https://pugjs.org/api/getting-started.html) as its default, but it also supports [Handlebars](https://www.npmjs.com/package/handlebars), and [EJS](https://www.npmjs.com/package/ejs), among others. To render template files, set the following [application setting properties](/{{ page.lang }}/4x/api.html#app.set), in the default `app.js` created by the generator: * `views`, the directory where the template files are located. Eg: `app.set('views', './views')`. This defaults to the `views` directory in the application root directory. * `view engine`, the template engine to use. For example, to use the Pug template engine: `app.set('view engine', 'pug')`. Then install the corresponding template engine npm package; for example to install Pug: ```bash $ npm install pug --save ```
Express-compliant template engines such as Pug export a function named `__express(filePath, options, callback)`, which `res.render()` calls to render the template code. Some template engines do not follow this convention. The [@ladjs/consolidate](https://www.npmjs.com/package/@ladjs/consolidate) library follows this convention by mapping all of the popular Node.js template engines, and therefore works seamlessly within Express.
After the view engine is set, you don't have to specify the engine or load the template engine module in your app; Express loads the module internally, for example: ```js app.set('view engine', 'pug') ``` Then, create a Pug template file named `index.pug` in the `views` directory, with the following content: ```pug html head title= title body h1= message ``` Create a route to render the `index.pug` file. If the `view engine` property is not set, you must specify the extension of the `view` file. Otherwise, you can omit it. ```js app.get('/', (req, res) => { res.render('index', { title: 'Hey', message: 'Hello there!' }) }) ``` When you make a request to the home page, the `index.pug` file will be rendered as HTML. The view engine cache does not cache the contents of the template's output, only the underlying template itself. The view is still re-rendered with every request even when the cache is on. --- --- layout: page title: Writing middleware for use in Express apps description: Learn how to write custom middleware functions for Express.js applications, including examples and best practices for enhancing request and response handling. menu: guide order: 2 redirect_from: "/guide/writing-middleware.html" --- # Writing middleware for use in Express apps

Overview

_Middleware_ functions are functions that have access to the [request object](/{{ page.lang }}/5x/api.html#req) (`req`), the [response object](/{{ page.lang }}/5x/api.html#res) (`res`), and the `next` function in the application's request-response cycle. The `next` function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware. Middleware functions can perform the following tasks: * Execute any code. * Make changes to the request and the response objects. * End the request-response cycle. * Call the next middleware in the stack. If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging. The following figure shows the elements of a middleware function call:
Elements of a middleware function call
HTTP method for which the middleware function applies.
Path (route) for which the middleware function applies.
The middleware function.
Callback argument to the middleware function, called "next" by convention.
HTTP response argument to the middleware function, called "res" by convention.
HTTP request argument to the middleware function, called "req" by convention.
Starting with Express 5, middleware functions that return a Promise will call `next(value)` when they reject or throw an error. `next` will be called with either the rejected value or the thrown Error.

Example

Here is an example of a simple "Hello World" Express application. The remainder of this article will define and add three middleware functions to the application: one called `myLogger` that prints a simple log message, one called `requestTime` that displays the timestamp of the HTTP request, and one called `validateCookies` that validates incoming cookies. ```js const express = require('express') const app = express() app.get('/', (req, res) => { res.send('Hello World!') }) app.listen(3000) ```

Middleware function myLogger

Here is a simple example of a middleware function called "myLogger". This function just prints "LOGGED" when a request to the app passes through it. The middleware function is assigned to a variable named `myLogger`. ```js const myLogger = function (req, res, next) { console.log('LOGGED') next() } ```
Notice the call above to `next()`. Calling this function invokes the next middleware function in the app. The `next()` function is not a part of the Node.js or Express API, but is the third argument that is passed to the middleware function. The `next()` function could be named anything, but by convention it is always named "next". To avoid confusion, always use this convention.
To load the middleware function, call `app.use()`, specifying the middleware function. For example, the following code loads the `myLogger` middleware function before the route to the root path (/). ```js const express = require('express') const app = express() const myLogger = function (req, res, next) { console.log('LOGGED') next() } app.use(myLogger) app.get('/', (req, res) => { res.send('Hello World!') }) app.listen(3000) ``` Every time the app receives a request, it prints the message "LOGGED" to the terminal. The order of middleware loading is important: middleware functions that are loaded first are also executed first. If `myLogger` is loaded after the route to the root path, the request never reaches it and the app doesn't print "LOGGED", because the route handler of the root path terminates the request-response cycle. The middleware function `myLogger` simply prints a message, then passes on the request to the next middleware function in the stack by calling the `next()` function.

Middleware function requestTime

Next, we'll create a middleware function called "requestTime" and add a property called `requestTime` to the request object. ```js const requestTime = function (req, res, next) { req.requestTime = Date.now() next() } ``` The app now uses the `requestTime` middleware function. Also, the callback function of the root path route uses the property that the middleware function adds to `req` (the request object). ```js const express = require('express') const app = express() const requestTime = function (req, res, next) { req.requestTime = Date.now() next() } app.use(requestTime) app.get('/', (req, res) => { let responseText = 'Hello World!
' responseText += `Requested at: ${req.requestTime}` res.send(responseText) }) app.listen(3000) ``` When you make a request to the root of the app, the app now displays the timestamp of your request in the browser.

Middleware function validateCookies

Finally, we'll create a middleware function that validates incoming cookies and sends a 400 response if cookies are invalid. Here's an example function that validates cookies with an external async service. ```js async function cookieValidator (cookies) { try { await externallyValidateCookie(cookies.testCookie) } catch { throw new Error('Invalid cookies') } } ``` Here, we use the [`cookie-parser`](/resources/middleware/cookie-parser.html) middleware to parse incoming cookies off the `req` object and pass them to our `cookieValidator` function. The `validateCookies` middleware returns a Promise that upon rejection will automatically trigger our error handler. ```js const express = require('express') const cookieParser = require('cookie-parser') const cookieValidator = require('./cookieValidator') const app = express() async function validateCookies (req, res, next) { await cookieValidator(req.cookies) next() } app.use(cookieParser()) app.use(validateCookies) // error handler app.use((err, req, res, next) => { res.status(400).send(err.message) }) app.listen(3000) ```
Note how `next()` is called after `await cookieValidator(req.cookies)`. This ensures that if `cookieValidator` resolves, the next middleware in the stack will get called. If you pass anything to the `next()` function (except the string `'route'` or `'router'`), Express regards the current request as being an error and will skip any remaining non-error handling routing and middleware functions.
Because you have access to the request object, the response object, the next middleware function in the stack, and the whole Node.js API, the possibilities with middleware functions are endless. For more information about Express middleware, see: [Using Express middleware](/{{ page.lang }}/guide/using-middleware.html).

Configurable middleware

If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters. File: `my-middleware.js` ```js module.exports = function (options) { return function (req, res, next) { // Implement the middleware function based on the options object next() } } ``` The middleware can now be used as shown below. ```js const mw = require('./my-middleware.js') app.use(mw({ option1: '1', option2: '2' })) ``` Refer to [cookie-session](https://github.com/expressjs/cookie-session) and [compression](https://github.com/expressjs/compression) for examples of configurable middleware. --- --- layout: page title: Express community description: Connect with the Express.js community, learn about the technical committee, find resources, explore community-contributed modules, and get involved in discussions. menu: resources order: 1 redirect_from: "/resources/community.html" --- # Community ## Technical committee The Express technical committee meets online every two weeks (as needed) to discuss development and maintenance of Express, and other issues relevant to the Express project. Each meeting is typically announced in an [expressjs/discussions issue](https://github.com/expressjs/discussions/issues) with a link to join or view the meeting, which is open to all observers. The meetings are recorded; for a list of the recordings, see the [Express.js YouTube channel](https://www.youtube.com/channel/UCYjxjAeH6TRik9Iwy5nXw7g). Members of the Express technical committee are: **Active:** - [@blakeembrey](https://github.com/blakeembrey) - Blake Embrey - [@crandmck](https://github.com/crandmck) - Rand McKinney - [@LinusU](https://github.com/LinusU) - Linus Unnebäck - [@ulisesgascon](https://github.com/ulisesGascon) - Ulises Gascón - [@sheplu](https://github.com/sheplu) - Jean Burellier - [@wesleytodd](https://github.com/wesleytodd) - Wes Todd - [@jonchurch](https://github.com/jonchurch) - Jon Church - [@ctcpip](https://github.com/ctcpip/) - Chris de Almeida **Inactive:** - [@dougwilson](https://github.com/dougwilson) - Douglas Wilson - [@hacksparrow](https://github.com/hacksparrow) - Hage Yaapa - [@jonathanong](https://github.com/jonathanong) - jongleberry - [@niftylettuce](https://github.com/niftylettuce) - niftylettuce - [@troygoode](https://github.com/troygoode) - Troy Goode ## Express is made of many modules Our vibrant community has created a large variety of extensions, [middleware modules](/{{ page.lang }}/resources/middleware.html) and higher-level frameworks. Additionally, the Express community maintains modules in these two GitHub orgs: - [jshttp](https://github.com/jshttp) modules providing useful utility functions; see [Utility modules](/{{ page.lang }}/resources/utils.html). - [pillarjs](https://github.com/pillarjs): low-level modules that Express uses internally. To keep up with what is going on in the whole community, check out the [ExpressJS StatusBoard](https://expressjs.github.io/statusboard/). ## Issues If you've come across what you think is a bug, or just want to make a feature request open a ticket in the [issue queue](https://github.com/expressjs/express/issues). ## Examples View dozens of Express application [examples](https://github.com/expressjs/express/tree/master/examples) in the repository covering everything from API design and authentication to template engine integration. ## Github Discussions The [GitHub Discussions](https://github.com/expressjs/discussions) section is an excellent space to engage in conversations about the development and maintenance of Express, as well as to share ideas and discuss topics related to its usage. # Branding of Express.js ## Express.js Logo Express is a project of the OpenJS Foundation. Please review the [trademark policy](https://trademark-policy.openjsf.org/) for information about permissible use of Express.js logos and marks.

Logotype

Express.js logo Express.js logo

Logomark

Express.js mark Express.js mark
--- --- layout: page title: Contributing to Express description: Find out how to contribute to Express.js, including guidelines for reporting issues, submitting pull requests, becoming a collaborator, and understanding security policies. menu: resources order: 5 redirect_from: "/resources/community.html" --- # Contributing to Express ### Looking to contribute to Expressjs.com? Click [here](#expressjs-website-contributing). Express and the other projects in the [expressjs organization on GitHub](https://github.com/expressjs) are projects of the [OpenJs Foundation](https://openjsf.org/). These projects are governed under the general policies and guidelines of the Node.js Foundation along with the additional guidelines below. * [Technical committee](#technical-committee) * [Community contributing guide](#community-contributing-guide) * [Collaborator's guide](#collaborators-guide) * [Security policies and procedures](#security-policies-and-procedures) ## Technical committee The Express technical committee consists of active project members, and guides development and maintenance of the Express project. For more information, see [Express Community - Technical committee](community.html#technical-committee). ## Community contributing guide The goal of this document is to create a contribution process that: * Encourages new contributions. * Encourages contributors to remain involved. * Avoids unnecessary processes and bureaucracy whenever possible. * Creates a transparent decision making process that makes it clear how contributors can be involved in decision making. ### Vocabulary * A **Contributor** is any individual creating or commenting on an issue or pull request. * A **Committer** is a subset of contributors who have been given write access to the repository. * A **Project Captain** is the lead maintainer of a repository. * A **TC (Technical Committee)** is a group of committers representing the required technical expertise to resolve rare disputes. * A **Triager** is a subset of contributors who have been given triage access to the repository. ### Logging Issues Log an issue for any question or problem you might have. When in doubt, log an issue, and any additional policies about what to include will be provided in the responses. The only exception is security disclosures which should be sent privately. Committers may direct you to another repository, ask for additional clarifications, and add appropriate metadata before the issue is addressed. Please be courteous and respectful. Every participant is expected to follow the project's Code of Conduct. ### Contributions Any change to resources in this repository must be through pull requests. This applies to all changes to documentation, code, binary files, etc. Even long term committers and TC members must use pull requests. No pull request can be merged without being reviewed. For non-trivial contributions, pull requests should sit for at least 36 hours to ensure that contributors in other timezones have time to review. Consideration should also be given to weekends and other holiday periods to ensure active committers all have reasonable time to become involved in the discussion and review process if they wish. The default for each contribution is that it is accepted once no committer has an objection. During a review, committers may also request that a specific contributor who is most versed in a particular area gives a "LGTM" before the PR can be merged. There is no additional "sign off" process for contributions to land. Once all issues brought by committers are addressed it can be landed by any committer. In the case of an objection being raised in a pull request by another committer, all involved committers should seek to arrive at a consensus by way of addressing concerns being expressed by discussion, compromise on the proposed change, or withdrawal of the proposed change. If a contribution is controversial and committers cannot agree about how to get it to land or if it should land then it should be escalated to the TC. TC members should regularly discuss pending contributions in order to find a resolution. It is expected that only a small minority of issues be brought to the TC for resolution and that discussion and compromise among committers be the default resolution mechanism. ### Becoming a Triager Anyone can become a triager! Read more about the process of being a triager in [the triage process document](https://github.com/expressjs/discussions/blob/master/Triager-Guide.md). Currently, any existing [organization member](https://github.com/orgs/expressjs/people) can nominate a new triager. If you are interested in becoming a triager, our best advice is to actively participate in the community by helping triaging issues and pull requests. As well we recommend to engage in other community activities like attending the TC meetings, and participating in the Slack discussions. If you feel ready and have been helping triage some issues, reach out to an active member of the organization to ask if they'd be willing to support you. If they agree, they can create a pull request to formalize your nomination. In the case of an objection to the nomination, the triage team is responsible for working with the individuals involved and finding a resolution. You can also reach out to any of the [organization members](https://github.com/orgs/expressjs/people) if you have questions or need guidance. ### Becoming a Committer All contributors who have landed significant and valuable contributions should be onboarded in a timely manner, and added as a committer, and be given write access to the repository. Committers are expected to follow this policy and continue to send pull requests, go through proper review, and have other committers merge their pull requests. ### TC Process The TC uses a "consensus seeking" process for issues that are escalated to the TC. The group tries to find a resolution that has no open objections among TC members. If a consensus cannot be reached that has no objections then a majority wins vote is called. It is also expected that the majority of decisions made by the TC are via a consensus seeking process and that voting is only used as a last-resort. Resolution may involve returning the issue to project captains with suggestions on how to move forward towards a consensus. It is not expected that a meeting of the TC will resolve all issues on its agenda during that meeting and may prefer to continue the discussion happening among the project captains. Members can be added to the TC at any time. Any TC member can nominate another committer to the TC and the TC uses its standard consensus seeking process to evaluate whether or not to add this new member. The TC will consist of a minimum of 3 active members and a maximum of 10. If the TC should drop below 5 members the active TC members should nominate someone new. If a TC member is stepping down, they are encouraged (but not required) to nominate someone to take their place. TC members will be added as admin's on the Github orgs, npm orgs, and other resources as necessary to be effective in the role. To remain "active" a TC member should have participation within the last 12 months and miss no more than six consecutive TC meetings. Our goal is to increase participation, not punish people for any lack of participation, this guideline should be only be used as such (replace an inactive member with a new active one, for example). Members who do not meet this are expected to step down. If A TC member does not step down, an issue can be opened in the discussions repo to move them to inactive status. TC members who step down or are removed due to inactivity will be moved into inactive status. Inactive status members can become active members by self nomination if the TC is not already larger than the maximum of 10. They will also be given preference if, while at max size, an active member steps down. ### Project Captains The Express TC can designate captains for individual projects/repos in the organizations. These captains are responsible for being the primary day-to-day maintainers of the repo on a technical and community front. Repo captains are empowered with repo ownership and package publication rights. When there are conflicts, especially on topics that effect the Express project at large, captains are responsible to raise it up to the TC and drive those conflicts to resolution. Captains are also responsible for making sure community members follow the community guidelines, maintaining the repo and the published package, as well as in providing user support. Like TC members, Repo captains are a subset of committers. To become a captain for a project the candidate is expected to participate in that project for at least 6 months as a committer prior to the request. They should have helped with code contributions as well as triaging issues. They are also required to have 2FA enabled on both their GitHub and npm accounts. Any TC member or an existing captain on the **same** repo can nominate another committer to the captain role. To do so, they should submit a PR to this document, updating the **Active Project Captains** section (while maintaining the sort order) with the project name, the nominee's GitHub handle, and their npm username (if different). * Repos can have as many captains as make sense for the scope of work. * A TC member or an existing repo captain **on the same project** can nominate a new captain. Repo captains from other projects should not nominate captains for a different project. The PR will require at least 2 approvals from TC members and 2 weeks hold time to allow for comment and/or dissent. When the PR is merged, a TC member will add them to the proper GitHub/npm groups. #### Active Projects and Captains The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#active-projects-and-members) #### Current Initiative Captains The list can be found at [https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains](https://github.com/expressjs/discussions/blob/HEAD/docs/contributing/captains_and_committers.md#current-initiative-captains) ### Inactivity and Emeritus Policy for Any Role To support the health and continuity of the project, all individuals holding a role within the community (such as Triager, Committer, WG member, Project Captain, or TC member) are encouraged to maintain active participation. Inactivity is defined as the absence of meaningful involvement in the project—such as contributions, code reviews, triage, meeting attendance, or discussion participation—for a continuous period of 6 months. #### Exceptions Anyone may request a temporary leave from active participation due to personal or professional reasons. In such cases, the individual should inform the relevant team or the Technical Committee (TC). During this time, the inactivity policy is paused, and the individual will not be flagged as inactive. #### Inactivity Process * If someone is deemed inactive, the individual may be transitioned to an emeritus role that reflects their past contributions. A best effort will be made to inform them that this has occurred. They may request to be reinstated when they are ready to be active again. * The emeritus status helps preserve a clear record of contributors who have meaningfully shaped the project over time. #### Accountability * The Technical Committee (TC) and the respective captains of each package/team are responsible for assessing activity levels and enacting this policy fairly and transparently, in coordination with other relevant teams. * In case of disagreement, the situation can be discussed and resolved by consensus within the TC or appropriate team. ### Developer's Certificate of Origin 1.1 ```text By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. ``` ## Collaborator's guide ### Website Issues Open issues for the expressjs.com website in https://github.com/expressjs/expressjs.com. For issues in other Express managed repos (everything in `expressjs`, `pillarjs` or `jshttp` other than `expressjs/express`), be sure to check their contributing guide and open issues and PRs in the appropriate repository. ### PRs and Code contributions * Tests must pass. * Follow the [JavaScript Standard Style](https://standardjs.com/) and `npm run lint`. * If you fix a bug, add a test. ### Branches Use the `master` branch for bug fixes or minor work that is intended for the current release stream. Use the correspondingly named branch, e.g. `6.x`, for anything intended for a future release of Express. ### Steps for contributing 1. Create an issue for the bug you want to fix or the feature that you want to add. 2. Create your own fork on GitHub, then checkout your fork. 3. Write your code in your local copy. It's good practice to create a branch for each new issue you work on, although not compulsory. 4. To run the test suite, first install the dependencies by running `npm install`, then run `npm test`. 5. Ensure your code is linted by running `npm run lint` -- fix any issue you see listed. 6. If the tests pass, you can commit your changes to your fork and then create a pull request from there. Make sure to reference your issue from the pull request comments by including the issue number e.g. `#123`. ### Issues which are questions We will typically close any vague issues or questions that are specific to some app you are writing. Please double check the docs and other references before being trigger happy with posting a question issue. Things that will help get your question issue looked at: * Full and runnable JS code. * Clear description of the problem or unexpected behavior. * Clear description of the expected result. * Steps you have taken to debug it yourself. If you post a question and do not outline the above items or make it easy for us to understand and reproduce your issue, it will be closed. If your question meets all of the above requirements but you do not believe it needs to be looked at by the maintainers (for example, if you are just looking for community input) please open it as a discussion topic instead of an issue. If you are unsure and open an issue, we may move it to discussions if we triage them and decide they do not need high visibility or maintainer input. ## Security Policies and Procedures This document outlines security procedures and general policies for the Express project. * [Reporting a Bug](#reporting-a-bug) * [Disclosure Policy](#disclosure-policy) * [Comments on this Policy](#comments-on-this-policy) ### Reporting a Bug The Express team and community take all security bugs in Express seriously. Thank you for improving the security of Express. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions. Report security bugs by emailing `express-security@lists.openjsf.org`. To ensure the timely response to your report, please ensure that the entirety of the report is contained within the email body and not solely behind a web link or an attachment. The lead maintainer will acknowledge your email within 48 hours, and will send a more detailed response within 48 hours indicating the next steps in handling your report. After the initial reply to your report, the security team will endeavor to keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance. Report security bugs in third-party modules to the person or team maintaining the module. ### Pre-release Versions Alpha and Beta releases are unstable and **not suitable for production use**. Vulnerabilities found in pre-releases should be reported according to the [Reporting a Bug](#reporting-a-bug) section. Due to the unstable nature of the branch it is not guaranteed that any fixes will be released in the next pre-release. ### Disclosure Policy When the security team receives a security bug report, they will assign it to a primary handler. This person will coordinate the fix and release process, involving the following steps: * Confirm the problem and determine the affected versions. * Audit code to find any potential similar problems. * Prepare fixes for all releases still under maintenance. These fixes will be released as fast as possible to npm. ### The Express Threat Model We are currently working on a new version of the security model, the most updated version can be found [here](https://github.com/expressjs/security-wg/blob/main/docs/ThreatModel.md) ### Comments on this Policy If you have suggestions on how this process could be improved please submit a pull request. ---- # Contributing to Expressjs.com {#expressjs-website-contributing} ### The Official Documentation of the Express.js Framework This is the contribution documentation for the [expressjs.com](https://github.com/expressjs/expressjs.com) website. #### Need some ideas? These are some typical issues. 1. **Website issues**: If you see anything on the site that could use a tune-up, think about how to fix it. - Display or screen sizing problems - Mobile responsiveness issues - Missing or broken accessibility features - Website outages - Broken links - Page structure or user interface enhancements 2. **Content Issues**: Fix anything related to site content or typos. - Spelling errors - Incorrect/outdated Express.js documentation - Missing content 3. **Translation Issues**: Fix any translation errors or contribute new content. - Fix spelling errors - Fix incorrect/poorly translated words - Check out the [Contributing translations](#contributing-translations) section below for a contributing guide. #### Want to work on a backlog issue? We often have bugs or enhancements that need work. You can find these under our repo's [Issues tab](https://github.com/expressjs/expressjs.com/issues). Check out the tags to find something that's a good match for you. #### Have an idea? Found a bug? If you've found a bug or a typo, or if you have an idea for an enhancement, you can: - Submit a [new issue](https://github.com/expressjs/expressjs.com/issues/new/choose) on our repo. Do this for larger proposals, or if you'd like to discuss or get feedback first. - Make a [GitHub pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). If you have already done work, and it's ready to go, feel free to send it our way. ## Getting Started The steps below will guide you through the Expressjs.com contribution process. #### Step 1: (OPTIONAL) Open a New Issue So you've found a problem that you want to fix, or have a site enhancement you want to make. 1. If you want to get feedback or discuss, open a discussion [issue](https://github.com/expressjs/expressjs.com/issues/new/choose) prior to starting work. This is not required, but encouraged for larger proposals. - While we highly encourage this step, it is only for submissions proposing significant change. It helps us to clarify and focus the work, and ensure it aligns with overall project priorities. - For submissions proposing minor improvements or corrections, this is not needed. You can skip this step. - When opening an issue please give it a title and fill in the description section. The more details you provide, the more feedback we can give. 2. After receiving your issue the Express.js documentation team will respond with feedback. We read every submission and always try to respond quickly with feedback. - For submissions proposing significant change, we encourage you to follow the review process before starting work. #### Step 2: Get the Application Code Base Clone the repo and get the code: ```sh git clone https://github.com/expressjs/expressjs.com.git ``` After you've got the code you're ready to start making your changes! But just in case you need a little extra explanation, this section below outlines the main sections of the code base, where most changes are likely to be made. **Markdown Page Files**: - These files render to html and make up the individual pages of the site. Most of the site's documentation text content is written in `md` files. - Change these to make changes to individual pages' content/text or markup. - Each language has its own complete set of pages, located under their respective language directories - all the Spanish markdown content is found in the `es` directory, for example. **Includes Partials and Layout Templates** - `_includes` are partials that are imported and reused across multiple pages. - These are used to import text content for reuse across pages, such as the API documentation, e.g., `_includes > api > en > 5x`, which is included in every language. - These are used to include the page components that make up site-wide user interface and periphery structure, e.g., Header, Footer, etc. - `_layouts` are the templates used to wrap the site's individual pages. - These are used to display the structure of the site's periphery, such as the header and footer, and for injecting and displaying individual markdown pages inside the `content` tag. **Blog Markdown Files** - These files make up the individual blog posts. If you want to contribute a blog post please follow the specific instructions for [How to write a blog post.](https://expressjs.com/en/blog/write-post.html) - Located under the `_posts` directory. **CSS or Javascript** - All css and js files are kept in `css` and `js` folders on the project root. The Express.js website is built using [Jekyll](https://jekyllrb.com/) and is hosted on [GitHub Pages](https://pages.github.com/). #### Step 3: Running the Application Now you'll need a way to see your changes, which means you'll need a running version of the application. You have two options. 1. __Run Locally__: This gets the local version of the application up and running on your machine. Follow our [Local Setup Guide](https://github.com/expressjs/expressjs.com?tab=readme-ov-file#build-the-website-locally) to use this option. - This is the recommended option for moderate to complex work. 2. __Run using Deploy Preview__: Use this option if you don't want to bother with a local installation. Part of our continuous integration pipeline includes [Netlify Deploy Preview](https://docs.netlify.com/deploy/deploy-types/deploy-previews/). 1. To use this you'll need to get your changes online - after you've made your first commit on your feature branch, make a *draft* pull request. 2. After the build steps are complete, you'll have access to a __Deploy Preview__ tab that will run your changes on the web, rebuilding after each commit is pushed. 3. After you are completely done your work, and it's ready for review, remove the draft status on your pull request and submit your work. ## Contributing translations We use Crowdin to manage our translations in multiple languages and achieve automatic translation with artificial intelligence. Since these translations can be inefficient in some cases, we need help from the community to provide accurate and helpful translations. The documentation is translated into these languages: - Chinese Simplified (`zh-cn`) - Chinese Traditional (`zh-tw`) - English (`en`) - French (`fr`) - German (`de`) - Italian (`it`) - Japanese (`ja`) - Korean (`ko`) - Brazilian Portuguese (`pt-br`) - Spanish (`es`) ### How to translate 1. Request to join the Express.js Website project on [Crowdin](https://express.crowdin.com/website) 2. [Select the language you want to translate](https://support.crowdin.com/for-translators/#starting-translation) 3. [Start translating](https://support.crowdin.com/online-editor/) --- --- layout: page title: Express glossary description: A comprehensive glossary of terms related to Express.js, Node.js, middleware, routing, and other key concepts to help you understand and use Express effectively. menu: resources order: 2 redirect_from: "/resources/glossary.html" --- # Glossary ### application In general, one or more programs that are designed to carry out operations for a specific purpose. In the context of Express, a program that uses the Express API running on the Node.js platform. Might also refer to an [app object](/{{ page.lang }}/api.html#express). ### API Application programming interface. Spell out the abbreviation when it is first used. ### Express A fast, un-opinionated, minimalist web framework for Node.js applications. In general, "Express" is preferred to "Express.js," though the latter is acceptable. ### libuv A multi-platform support library which focuses on asynchronous I/O, primarily developed for use by Node.js. ### middleware A function that is invoked by the Express routing layer before the final request handler, and thus sits in the middle between a raw request and the final intended route. A few fine points of terminology around middleware: * `var foo = require('middleware')` is called _requiring_ or _using_ a Node.js module. Then the statement `var mw = foo()` typically returns the middleware. * `app.use(mw)` is called _adding the middleware to the global processing stack_. * `app.get('/foo', mw, function (req, res) { ... })` is called _adding the middleware to the "GET /foo" processing stack_. ### Node.js A software platform that is used to build scalable network applications. Node.js uses JavaScript as its scripting language, and achieves high throughput via non-blocking I/O and a single-threaded event loop. See [nodejs.org](https://nodejs.org/en/). **Usage note**: Initially, "Node.js," thereafter "Node". ### open-source, open source When used as an adjective, hyphenate; for example: "This is open-source software." See [Open-source software on Wikipedia](http://en.wikipedia.org/wiki/Open-source_software). {% capture english-rules %} Although it is common not to hyphenate this term, we are using the standard English rules for hyphenating a compound adjective. {% endcapture %} {% include admonitions/note.html content=english-rules %} ### request An HTTP request. A client submits an HTTP request message to a server, which returns a response. The request must use one of several [request methods](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods) such as GET, POST, and so on. ### response An HTTP response. A server returns an HTTP response message to the client. The response contains completion status information about the request and might also contain requested content in its message body. ### route Part of a URL that identifies a resource. For example, in `http://foo.com/products/id`, "/products/id" is the route. ### router See [router](/{{ page.lang }}/api.html#router) in the API reference. --- --- layout: middleware title: Express body-parser middleware menu: resources redirect_from: '/resources/middleware/body-parser.html' module: body-parser --- --- --- layout: middleware title: Express compression middleware menu: resources redirect_from: '/resources/middleware/compression.html' module: compression --- --- --- layout: middleware title: Express connect-rid middleware menu: resources redirect_from: '/resources/middleware/connect-rid.html' module: connect-rid --- --- --- layout: middleware title: Express cookie-parser middleware menu: resources redirect_from: '/resources/middleware/cookie-parser.html' module: cookie-parser --- --- --- layout: middleware title: Express cookie-session middleware menu: resources redirect_from: '/resources/middleware/cookie-session.html' module: cookie-session --- --- --- layout: middleware title: Express cors middleware menu: resources redirect_from: '/resources/middleware/cors.html' module: cors --- --- --- layout: middleware title: Express errorhandler middleware menu: resources redirect_from: '/resources/middleware/errorhandler.html' module: errorhandler --- --- --- layout: middleware title: Express method-override middleware menu: resources redirect_from: '/resources/middleware/method-override.html' module: method-override --- --- --- layout: middleware title: Express morgan middleware menu: resources redirect_from: '/resources/middleware/morgan.html' module: morgan --- --- --- layout: middleware title: Express multer middleware menu: resources redirect_from: '/resources/middleware/multer.html' module: multer --- --- --- layout: middleware title: Express response-time middleware menu: resources redirect_from: '/resources/middleware/response-time.html' module: response-time --- --- --- layout: middleware title: Express serve-favicon middleware menu: resources redirect_from: '/resources/middleware/serve-favicon.html' module: serve-favicon --- --- --- layout: middleware title: Express serve-index middleware menu: resources redirect_from: '/resources/middleware/serve-index.html' module: serve-index --- --- --- layout: middleware title: Express serve-static middleware menu: resources redirect_from: '/resources/middleware/serve-static.html' module: serve-static --- --- --- layout: middleware title: Express session middleware menu: resources redirect_from: '/resources/middleware/session.html' module: session --- --- --- layout: middleware title: Express timeout middleware menu: resources redirect_from: '/resources/middleware/timeout.html' module: timeout --- --- --- layout: middleware title: Express vhost middleware menu: resources redirect_from: '/resources/middleware/vhost.html' module: vhost --- --- --- layout: middleware title: Express middleware description: Explore a list of Express.js middleware modules maintained by the Express team and the community, including built-in middleware and popular third-party modules. menu: resources order: 3 redirect_from: "/resources/middleware.html" module: mw-home --- ## Express middleware The Express middleware modules listed here are maintained by the [Expressjs team](https://github.com/orgs/expressjs/people). | Middleware module | Description | | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | [body-parser](/{{page.lang}}/resources/middleware/body-parser.html) | Parse HTTP request body. | | [compression](/{{page.lang}}/resources/middleware/compression.html) | Compress HTTP responses. | | [connect-rid](/{{page.lang}}/resources/middleware/connect-rid.html) | Generate unique request ID. | | [cookie-parser](/{{page.lang}}/resources/middleware/cookie-parser.html) | Parse cookie header and populate `req.cookies`. See also [cookies](https://github.com/jed/cookies). | | [cookie-session](/{{page.lang}}/resources/middleware/cookie-session.html) | Establish cookie-based sessions. | | [cors](/{{page.lang}}/resources/middleware/cors.html) | Enable cross-origin resource sharing (CORS) with various options. | | [errorhandler](/{{page.lang}}/resources/middleware/errorhandler.html) | Development error-handling/debugging. | | [method-override](/{{page.lang}}/resources/middleware/method-override.html) | Override HTTP methods using header. | | [morgan](/{{page.lang}}/resources/middleware/morgan.html) | HTTP request logger. | | [multer](/{{page.lang}}/resources/middleware/multer.html) | Handle multi-part form data. | | [response-time](/{{page.lang}}/resources/middleware/response-time.html) | Record HTTP response time. | | [serve-favicon](/{{page.lang}}/resources/middleware/serve-favicon.html) | Serve a favicon. | | [serve-index](/{{page.lang}}/resources/middleware/serve-index.html) | Serve directory listing for a given path. | | [serve-static](/{{page.lang}}/resources/middleware/serve-static.html) | Serve static files. | | [session](/{{page.lang}}/resources/middleware/session.html) | Establish server-based sessions (development only). | | [timeout](/{{page.lang}}/resources/middleware/timeout.html) | Set a timeout perioHTTP request processing. | | [vhost](/{{page.lang}}/resources/middleware/vhost.html) | Create virtual domains. | ## Additional middleware modules These are some additional popular middleware modules. {% include community-caveat.html %} | Middleware module | Description | | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | [helmet](https://github.com/helmetjs/helmet) | Helps secure your apps by setting various HTTP headers. | | [passport](https://github.com/jaredhanson/passport) | Authentication using "strategies" such as OAuth, OpenID and many others. See [passportjs.org](https://passportjs.org/) for more information. | --- --- layout: page title: Express utilities description: Discover utility modules related to Express.js and Node.js, including tools for cookies, CSRF protection, URL parsing, routing, and more to enhance your applications. menu: resources order: 4 redirect_from: "/resources/utilities.html" --- ## Express utility functions The [pillarjs](https://github.com/pillarjs) GitHub organization contains a number of modules for utility functions that may be generally useful. | Utility modules | Description| |-----------------|------------| | [cookies](https://www.npmjs.com/package/cookies) | Get and set HTTP(S) cookies that can be signed to prevent tampering, using Keygrip. Can be used with the Node.js HTTP library or as Express middleware.| | [csrf](https://www.npmjs.com/package/csrf) | Contains the logic behind CSRF token creation and verification. Use this module to create custom CSRF middleware.| | [finalhandler](https://www.npmjs.com/package/finalhandler) | Function to invoke as the final step to respond to HTTP request.| | [parseurl](https://www.npmjs.com/package/parseurl) | Parse a URL with caching. | | [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) | Turn an Express-style path string such as ``/user/:name` into a regular expression.| | [resolve-path](https://www.npmjs.com/package/resolve-path) | Resolves a relative path against a root path with validation. | | [router](https://www.npmjs.com/package/router) | Simple middleware-style router. | | [send](https://www.npmjs.com/package/send) | Library for streaming files as a HTTP response, with support for partial responses (ranges), conditional-GET negotiation, and granular events.| For additional low-level HTTP-related modules, see [jshttp](http://jshttp.github.io/). --- --- layout: page title: Express basic routing description: Learn the fundamentals of routing in Express.js applications, including how to define routes, handle HTTP methods, and create route handlers for your web server. menu: starter order: 4 redirect_from: "/starter/basic-routing.html" --- # Basic routing _Routing_ refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on). Each route can have one or more handler functions, which are executed when the route is matched. Route definition takes the following structure: ```js app.METHOD(PATH, HANDLER) ``` Where: - `app` is an instance of `express`. - `METHOD` is an [HTTP request method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods), in lowercase. - `PATH` is a path on the server. - `HANDLER` is the function executed when the route is matched.
This tutorial assumes that an instance of `express` named `app` is created and the server is running. If you are not familiar with creating an app and starting it, see the [Hello world example](/{{ page.lang }}/starter/hello-world.html).
The following examples illustrate defining simple routes. Respond with `Hello World!` on the homepage: ```js app.get('/', (req, res) => { res.send('Hello World!') }) ``` Respond to a POST request on the root route (`/`), the application's home page: ```js app.post('/', (req, res) => { res.send('Got a POST request') }) ``` Respond to a PUT request to the `/user` route: ```js app.put('/user', (req, res) => { res.send('Got a PUT request at /user') }) ``` Respond to a DELETE request to the `/user` route: ```js app.delete('/user', (req, res) => { res.send('Got a DELETE request at /user') }) ``` For more details about routing, see the [routing guide](/{{ page.lang }}/guide/routing.html). --- --- layout: page title: Express examples description: Explore a collection of Express.js application examples covering various use cases, integrations, and advanced configurations to help you learn and build your projects. menu: starter order: 6 redirect_from: "/starter/examples.html" --- {% capture examples %}{% include readmes/express-master/examples.md %}{% endcapture %} {{ examples | replace: "](.", "](https://github.com/expressjs/express/tree/master/examples" }} ## Additional examples These are some additional examples with more extensive integrations. {% include community-caveat.html %} - [prisma-fullstack](https://github.com/prisma/prisma-examples/tree/latest/pulse/fullstack-simple-chat) - Fullstack app with Express and Next.js using [Prisma](https://www.npmjs.com/package/prisma) as an ORM - [prisma-rest-api-ts](https://github.com/prisma/prisma-examples/tree/latest/orm/express) - REST API with Express in TypeScript using [Prisma](https://www.npmjs.com/package/prisma) as an ORM --- --- layout: page title: Express FAQ description: Find answers to frequently asked questions about Express.js, including topics on application structure, models, authentication, template engines, error handling, and more. menu: starter order: 7 redirect_from: "/starter/faq.html" --- # FAQ ## How should I structure my application? There is no definitive answer to this question. The answer depends on the scale of your application and the team that is involved. To be as flexible as possible, Express makes no assumptions in terms of structure. Routes and other application-specific logic can live in as many files as you wish, in any directory structure you prefer. View the following examples for inspiration: * [Route listings](https://github.com/expressjs/express/blob/4.13.1/examples/route-separation/index.js#L32-L47) * [Route map](https://github.com/expressjs/express/blob/4.13.1/examples/route-map/index.js#L52-L66) * [MVC style controllers](https://github.com/expressjs/express/tree/master/examples/mvc) Also, there are third-party extensions for Express, which simplify some of these patterns: * [Resourceful routing](https://github.com/expressjs/express-resource) ## How do I define models? Express has no notion of a database. This concept is left up to third-party Node modules, allowing you to interface with nearly any database. See [LoopBack](http://loopback.io) for an Express-based framework that is centered around models. ## How can I authenticate users? Authentication is another opinionated area that Express does not venture into. You may use any authentication scheme you wish. For a simple username / password scheme, see [this example](https://github.com/expressjs/express/tree/master/examples/auth). ## Which template engines does Express support? Express supports any template engine that conforms with the `(path, locals, callback)` signature. To normalize template engine interfaces and caching, see the [consolidate.js](https://github.com/visionmedia/consolidate.js) project for support. Unlisted template engines might still support the Express signature. For more information, see [Using template engines with Express](/{{page.lang}}/guide/using-template-engines.html). ## How do I handle 404 responses? In Express, 404 responses are not the result of an error, so the error-handler middleware will not capture them. This behavior is because a 404 response simply indicates the absence of additional work to do; in other words, Express has executed all middleware functions and routes, and found that none of them responded. All you need to do is add a middleware function at the very bottom of the stack (below all other functions) to handle a 404 response: ```js app.use((req, res, next) => { res.status(404).send("Sorry can't find that!") }) ``` Add routes dynamically at runtime on an instance of `express.Router()` so the routes are not superseded by a middleware function. ## How do I setup an error handler? You define error-handling middleware in the same way as other middleware, except with four arguments instead of three; specifically with the signature `(err, req, res, next)`: ```js app.use((err, req, res, next) => { console.error(err.stack) res.status(500).send('Something broke!') }) ``` For more information, see [Error handling](/{{ page.lang }}/guide/error-handling.html). ## How do I render plain HTML? You don't! There's no need to "render" HTML with the `res.render()` function. If you have a specific file, use the `res.sendFile()` function. If you are serving many assets from a directory, use the `express.static()` middleware function. ## What version of Node.js does Express require? * [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. * [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. --- --- layout: page title: Express application generator description: Learn how to use the Express application generator tool to quickly create a skeleton for your Express.js applications, streamlining setup and configuration. menu: starter order: 3 redirect_from: "/starter/generator.html" --- # Express application generator Use the application generator tool, `express-generator`, to quickly create an application skeleton. You can run the application generator with the `npx` command (available in Node.js 8.2.0). ```bash $ npx express-generator ``` For earlier Node versions, install the application generator as a global npm package and then launch it: ```bash $ npm install -g express-generator $ express ``` Display the command options with the `-h` option: ```bash $ express -h Usage: express [options] [dir] Options: -h, --help output usage information --version output the version number -e, --ejs add ejs engine support --hbs add handlebars engine support --pug add pug engine support -H, --hogan add hogan.js engine support --no-view generate without view engine -v, --view add view support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade) -c, --css add stylesheet support (less|stylus|compass|sass) (defaults to plain css) --git add .gitignore -f, --force force on non-empty directory ``` For example, the following creates an Express app named _myapp_. The app will be created in a folder named _myapp_ in the current working directory and the view engine will be set to Pug: ```bash $ express --view=pug myapp create : myapp create : myapp/package.json create : myapp/app.js create : myapp/public create : myapp/public/javascripts create : myapp/public/images create : myapp/routes create : myapp/routes/index.js create : myapp/routes/users.js create : myapp/public/stylesheets create : myapp/public/stylesheets/style.css create : myapp/views create : myapp/views/index.pug create : myapp/views/layout.pug create : myapp/views/error.pug create : myapp/bin create : myapp/bin/www ``` Then install dependencies: ```bash $ cd myapp $ npm install ``` On MacOS or Linux, run the app with this command: ```bash $ DEBUG=myapp:* npm start ``` On Windows Command Prompt, use this command: ```bash > set DEBUG=myapp:* & npm start ``` On Windows PowerShell, use this command: ```bash PS> $env:DEBUG='myapp:*'; npm start ``` Then, load `http://localhost:3000/` in your browser to access the app. The generated app has the following directory structure: ```bash . ├── app.js ├── bin │ └── www ├── package.json ├── public │ ├── images │ ├── javascripts │ └── stylesheets │ └── style.css ├── routes │ ├── index.js │ └── users.js └── views ├── error.pug ├── index.pug └── layout.pug 7 directories, 9 files ```
The app structure created by the generator is just one of many ways to structure Express apps. Feel free to use this structure or modify it to best suit your needs.
--- --- layout: page title: Express "Hello World" example description: Get started with Express.js by building a simple 'Hello World' application, demonstrating the basic setup and server creation for beginners. menu: starter order: 2 redirect_from: "/starter/hello-world.html" --- # Hello world example
Embedded below is essentially the simplest Express app you can create. It is a single file app — _not_ what you'd get if you use the [Express generator](/{{ page.lang }}/starter/generator.html), which creates the scaffolding for a full app with numerous JavaScript files, Jade templates, and sub-directories for various purposes.
```js const express = require('express') const app = express() const port = 3000 app.get('/', (req, res) => { res.send('Hello World!') }) app.listen(port, () => { console.log(`Example app listening on port ${port}`) }) ``` This app starts a server and listens on port 3000 for connections. The app responds with "Hello World!" for requests to the root URL (`/`) or _route_. For every other path, it will respond with a **404 Not Found**. ### Running Locally First create a directory named `myapp`, change to it and run `npm init`. Then, install `express` as a dependency, as per the [installation guide](/{{ page.lang }}/starter/installing.html). In the `myapp` directory, create a file named `app.js` and copy the code from the example above.
The `req` (request) and `res` (response) are the exact same objects that Node provides, so you can invoke `req.pipe()`, `req.on('data', callback)`, and anything else you would do without Express involved.
Run the app with the following command: ```bash $ node app.js ``` Then, load `http://localhost:3000/` in a browser to see the output. --- --- layout: page title: Installing Express description: Learn how to install Express.js in your Node.js environment, including setting up your project directory and managing dependencies with npm. menu: starter order: 1 redirect_from: "/starter/installing.html" --- # Installing Assuming you've already installed [Node.js](https://nodejs.org/), create a directory to hold your application, and make that your working directory. * [Express 4.x](/{{ page.lang }}/4x/api.html) requires Node.js 0.10 or higher. * [Express 5.x](/{{ page.lang }}/5x/api.html) requires Node.js 18 or higher. ```bash $ mkdir myapp $ cd myapp ``` Use the `npm init` command to create a `package.json` file for your application. For more information on how `package.json` works, see [Specifics of npm's package.json handling](https://docs.npmjs.com/files/package.json). ```bash $ npm init ``` This command prompts you for a number of things, such as the name and version of your application. For now, you can simply hit RETURN to accept the defaults for most of them, with the following exception: ``` entry point: (index.js) ``` Enter `app.js`, or whatever you want the name of the main file to be. If you want it to be `index.js`, hit RETURN to accept the suggested default file name. Now, install Express in the `myapp` directory and save it in the dependencies list. For example: ```bash $ npm install express ``` To install Express temporarily and not add it to the dependencies list: ```bash $ npm install express --no-save ```
By default with version npm 5.0+, `npm install` adds the module to the `dependencies` list in the `package.json` file; with earlier versions of npm, you must specify the `--save` option explicitly. Then, afterwards, running `npm install` in the app directory will automatically install modules in the dependencies list.
--- --- layout: page title: Serving static files in Express description: Understand how to serve static files like images, CSS, and JavaScript in Express.js applications using the built-in 'static' middleware. menu: starter order: 5 redirect_from: "/starter/static-files.html" --- # Serving static files in Express To serve static files such as images, CSS files, and JavaScript files, use the `express.static` built-in middleware function in Express. The function signature is: ```js express.static(root, [options]) ``` The `root` argument specifies the root directory from which to serve static assets. For more information on the `options` argument, see [express.static](/{{page.lang}}/5x/api.html#express.static). For example, use the following code to serve images, CSS files, and JavaScript files in a directory named `public`: ```js app.use(express.static('public')) ``` Now, you can load the files that are in the `public` directory: ```text http://localhost:3000/images/kitten.jpg http://localhost:3000/css/style.css http://localhost:3000/js/app.js http://localhost:3000/images/bg.png http://localhost:3000/hello.html ```
Express looks up the files relative to the static directory, so the name of the static directory is not part of the URL.
To use multiple static assets directories, call the `express.static` middleware function multiple times: ```js app.use(express.static('public')) app.use(express.static('files')) ``` Express looks up the files in the order in which you set the static directories with the `express.static` middleware function. {% capture alert_content %} For best results, [use a reverse proxy](/{{page.lang}}/advanced/best-practice-performance.html#use-a-reverse-proxy) cache to improve performance of serving static assets. {% endcapture %} {% include admonitions/note.html content=alert_content %} To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the `express.static` function, [specify a mount path](/{{ page.lang }}/5x/api.html#app.use) for the static directory, as shown below: ```js app.use('/static', express.static('public')) ``` Now, you can load the files that are in the `public` directory from the `/static` path prefix. ```text http://localhost:3000/static/images/kitten.jpg http://localhost:3000/static/css/style.css http://localhost:3000/static/js/app.js http://localhost:3000/static/images/bg.png http://localhost:3000/static/hello.html ``` However, the path that you provide to the `express.static` function is relative to the directory from where you launch your `node` process. If you run the express app from another directory, it's safer to use the absolute path of the directory that you want to serve: ```js const path = require('path') app.use('/static', express.static(path.join(__dirname, 'public'))) ``` For more details about the `serve-static` function and its options, see [serve-static](/resources/middleware/serve-static.html). --- --- layout: page title: Version Support description: Find information about the support schedule for different Express.js versions, including which versions are currently maintained and end-of-life policies. menu: support --- # Version Support Only the latest version of any given major release line is supported. Versions that are EOL (end-of-life) _may_ receive updates for critical security vulnerabilities, but the Express team offers no guarantee and does not plan to address or release fixes for any issues found. | Major Version | Minimum Node.js Version | Support Start Date | Support End Date | | -- | -- | -- | -- | | [**v5.x**{: .supported }](/{{page.lang}}/5x/api.html){: .ignore-underline} | 18 | September 2024 | **ongoing**{: .supported } | | [**v4.x**{: .supported }](/{{page.lang}}/4x/api.html){: .ignore-underline} | 0.10.0 | April 2014 | **ongoing**{: .supported } | | [**v3.x**{: .eol }](/{{page.lang}}/3x/api.html){: .ignore-underline} | 0.8.0 | October 2012 | July 2015 | | [**v2.x**{: .eol }](/2x/){: .ignore-underline} | 0.4.1 | March 2011 | July 2012 | | **v1.x**{: .eol } | 0.2.0 | December 2010 | March 2011 | | **v0.14.x**{: .eol } | 0.1.98 | December 2010 | December 2010 | ## Commercial Support Options If you are unable to update to a supported version of Express, please contact one of our partners to receive security updates: - [HeroDevs Never-Ending Support](http://www.herodevs.com/support/express-nes?utm_source=expressjs&utm_medium=link&utm_campaign=express_eol_page)