How to Enable CORS in Express Using the npm cors Middleware

Install the cors package and register it with app.use(cors()) before your route handlers to automatically inject the required Access-Control-Allow-Origin headers into every response.

The Express framework (expressjs/express) handles cross-origin requests through its middleware pipeline defined in lib/application.js. When you launch your application via npm start, adding the cors middleware early in the stack ensures that all incoming requests receive the proper HTTP headers to communicate with browsers on different origins.

Install the cors Package

Add the official middleware to your project before configuring your server.

npm install cors

This package provides a thin, well-tested wrapper that sets the appropriate Access-Control-* response headers based on your configuration options.

Enable CORS Globally for All Routes

The most common approach is to register the middleware at the application level using app.use(). According to the Express source in lib/application.js, this method mounts the middleware function so it executes for every incoming request before reaching your route handlers.

const express = require('express');
const cors = require('cors');

const app = express();

// Register cors middleware first in the stack
app.use(cors());

// Subsequent middleware and routes
app.use(express.json());
app.get('/api/data', (req, res) => {
  res.json({ status: 'accessible from any origin' });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

With this default configuration, every response includes Access-Control-Allow-Origin: *, allowing requests from any domain.

Configure Specific Origins and Methods

For production applications, restrict access to known domains rather than allowing all origins.

const corsOptions = {
  origin: ['https://example.com', 'https://app.example.com'],
  methods: ['GET', 'POST', 'PUT'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true
};

app.use(cors(corsOptions));

This setup inspects the Origin header of each request. Only browsers sending requests from the specified domains receive the CORS headers; others are blocked by the browser's same-origin policy.

Apply CORS to Specific Routes Only

You can apply different CORS rules to individual endpoints while keeping a global default. This pattern leverages the middleware architecture in lib/express.js where functions can be mounted on specific paths.

// Global: allow any origin on public routes
app.use(cors());

app.get('/public', (req, res) => {
  res.json({ data: 'public information' });
});

// Private: restrict to single origin
const privateCors = cors({ origin: 'https://admin.internal.com' });
app.get('/admin', privateCors, (req, res) => {
  res.json({ data: 'sensitive information' });
});

The privateCors function executes only for requests matching /admin, leaving other routes unaffected by its specific headers.

Understanding the Middleware Architecture

Express's core design centers on a middleware stack implemented in lib/application.js. When you call app.use(cors()), the application pushes your middleware function into an internal array that processes requests sequentially.

As the request flows through the stack:

  1. Express creates req and res objects.
  2. The cors() middleware inspects the request, adds the necessary headers to res, and calls next().
  3. Control passes to subsequent middleware or route handlers.
  4. The final handler sends the response with CORS headers already attached.

Because cors() automatically handles pre-flight OPTIONS requests, you do not need to implement separate logic for the browser's preliminary security checks.

Running Your Application with npm start

In the expressjs/express repository, the default npm start command executes node ./examples/web-service/index.js. Regardless of your specific entry point, ensure your application initializes the middleware before starting the server.

Update your package.json scripts section:

{
  "scripts": {
    "start": "node index.js"
  }
}

Then structure your entry file to mount cors() before route definitions:

// index.js
const express = require('express');
const cors = require('cors');
const app = express();

// Critical: cors must come before route definitions
app.use(cors());

app.get('/', (req, res) => {
  res.json({ message: 'CORS enabled across all origins' });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});

Execute the following to launch:

npm install
npm start

Visiting your endpoint from a browser on a different origin (or using a tool like curl with the -H "Origin: http://example.com" flag) will now succeed because the middleware injects the required headers before the response is sent.

Summary

  • Install the cors package via npm to add CORS functionality to your Express application.
  • Register early using app.use(cors()) in lib/application.js's middleware stack to ensure all routes inherit the headers.
  • Configure origins by passing an options object to restrict access to specific domains rather than using the wildcard *.
  • Handle pre-flight requests automatically without writing separate OPTIONS route handlers.
  • Test with npm start by placing the middleware initialization in your entry file before route definitions and the app.listen() call.

Frequently Asked Questions

What does the cors middleware actually modify in the request-response cycle?

The cors middleware intercepts outgoing responses in the middleware chain defined in lib/application.js and appends HTTP headers like Access-Control-Allow-Origin and Access-Control-Allow-Methods to the res object. It also automatically terminates the request-response cycle for OPTIONS pre-flight requests by sending the appropriate headers immediately, preventing unnecessary processing by subsequent route handlers.

Why must I place app.use(cors()) before my route definitions?

Express executes middleware in the exact order registered via app.use() as implemented in lib/application.js. If you mount routes before the cors middleware, those route handlers will send responses before the CORS headers are attached, causing browsers to block cross-origin requests. Registering cors() first ensures the headers are present before any response is transmitted.

Can I enable CORS for only one specific route while disabling it for others?

Yes. Instead of using app.use(cors()) globally, pass the cors middleware directly to the specific route method: app.get('/api', cors(), handler). This mounts the middleware only on that specific path, leaving other routes without CORS headers. You can also apply different cors configurations with distinct options objects to different endpoints to vary security levels across your API.

How do I handle credentials when using the cors package?

Set the credentials: true option in your configuration and specify an explicit origin (never * when credentials are involved). Browsers reject wildcard origins when credentials are included. Your configuration should resemble { origin: 'https://trusted.com', credentials: true }. The middleware will then set the Access-Control-Allow-Credentials: true header, permitting cookies and authorization headers to cross origin boundaries.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →