How to Configure the CORS npm Package in Express: A Complete Guide
To configure the CORS npm package in Express, install the cors package and register it as global middleware using app.use(cors()) before your route handlers to enable cross-origin requests from your frontend application.
The expressjs/express repository provides a lightweight core that handles routing and middleware orchestration through a sequential stack. When you configure the CORS npm package in Express, you are inserting a specialized middleware function that inspects incoming Origin headers and sets the appropriate Access-Control-* response headers before your application logic executes.
Understanding CORS Middleware in Express
How Express Middleware Works
Express treats any function with the signature (req, res, next) as middleware. The app.use() method in lib/application.js (lines 190-230) attaches these functions to an internal stack, executing them sequentially for every incoming request. When you configure the CORS npm package, you are adding its handler to this stack.
The CORS Request Flow
- The browser sends a request with an
Originheader indicating the frontend domain - Express passes the request through the middleware stack
- The CORS middleware checks the origin against your configured whitelist
- If allowed, the middleware sets
Access-Control-Allow-Originand related headers - For pre-flight
OPTIONSrequests, the middleware responds immediately with a 204 or 200 status
Installing and Configuring the CORS npm Package
First, install the package from npm:
npm install cors
Global Configuration for All Routes
The most common pattern is to register CORS globally before your route handlers. This ensures every request, including pre-flight OPTIONS requests, is processed correctly:
const express = require('express')
const cors = require('cors')
const app = express()
// Register CORS for *all* routes
app.use(cors())
app.get('/hello', (req, res) => {
res.json({ msg: 'Hello from Express + CORS' })
})
app.listen(3000, () => console.log('Server listening on http://localhost:3000'))
Restricting to Specific Origins
For production applications, you should whitelist specific origins rather than allowing all domains. You can also enable credentials to allow cookies and authorization headers:
app.use(
cors({
origin: 'https://my-frontend.example.com', // only this origin is permitted
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true // allow cookies / Authorization header
})
)
Scoped CORS for API Routes
You can apply CORS only to specific path prefixes using app.use([path,] middleware). This leverages the path-matching logic in lib/application.js:
const apiRouter = express.Router()
// Apply CORS *only* to routes under /api
apiRouter.use(
cors({
origin: ['https://app.example.com', 'https://admin.example.com']
})
)
apiRouter.get('/users', (req, res) => {
res.json([{ id: 1, name: 'Alice' }])
})
app.use('/api', apiRouter) // mount at /api
Handling Pre-flight Requests
Some legacy browsers (IE11, older mobile browsers) expect a 200 status code instead of the standard 204 for pre-flight responses. Configure this using optionsSuccessStatus:
app.use(
cors({
origin: '*',
optionsSuccessStatus: 200 // some browsers expect 200 instead of 204
})
)
Advanced CORS Configuration Options
The cors package provides additional options for complex scenarios:
allowedHeaders: Specify which headers can be used in the request (e.g.,['Content-Type', 'Authorization'])exposedHeaders: Headers that browsers are allowed to access (e.g.,['X-Request-ID'])maxAge: How long (in seconds) browsers can cache pre-flight responses, reducing redundantOPTIONSrequests
Summary
- Install the
corspackage via npm to handle cross-origin requests in Express applications - Register globally using
app.use(cors())before route handlers to ensure all requests (including pre-flight) are processed - Restrict origins in production by passing an
originoption instead of using the default wildcard (*) - Enable credentials with
credentials: truewhen your frontend needs to send cookies or authorization headers - Scope to paths using
app.use('/api', cors())to apply CORS only to specific route prefixes, leveraging the path-matching logic inlib/application.js
Frequently Asked Questions
How do I enable CORS only for specific routes in Express?
Use app.use() with a path argument to scope CORS to specific route prefixes. For example, app.use('/api', cors()) applies the middleware only to routes starting with /api. You can also create a Router instance, apply CORS to it, and then mount the router at a specific path using app.use('/api', apiRouter).
Why are my cookies not being sent in cross-origin requests?
By default, browsers do not send cookies or authorization headers in cross-origin requests unless explicitly permitted. You must set credentials: true in your CORS configuration and ensure your origin option is not set to * (wildcards cannot be used with credentials). The specific origin must be explicitly listed, such as origin: 'https://myapp.com'.
What is the difference between simple requests and pre-flight requests in CORS?
Simple requests (GET, POST with specific content-types, HEAD) are sent directly with CORS headers attached to the response. Pre-flight requests occur when the browser sends an OPTIONS request first to check if the actual request is safe to send. The cors npm package automatically handles these OPTIONS requests, but you can customize the response status using optionsSuccessStatus for compatibility with older browsers.
Where should I place the CORS middleware in my Express application?
Always place CORS middleware before your route handlers and other middleware that might terminate the request. According to the implementation in lib/application.js, Express processes middleware in the order they are registered using app.use(). If you place CORS after route handlers, the headers won't be set because the response will have already been sent or the route handler will have ended the request-response cycle.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →