@koa/cors

Cross-Origin Resource Sharing (CORS) middleware for Koa that sets `Access-Control-*` headers and handles preflight `OPTIONS` requests.

Since Koa 2 Spec ↗

Syntax

import cors from '@koa/cors';
app.use(cors([options]));

Parameters

NameTypeRequiredDescription
options object No Options: `origin` (string, function, or `"*"`), `allowMethods` (default `GET,HEAD,PUT,POST,DELETE,PATCH`), `allowHeaders`, `exposeHeaders`, `credentials` (boolean, default false), `maxAge` (preflight cache seconds), `keepHeadersOnError` (default true).

Returns

function — Koa middleware that adds CORS headers and handles preflight requests.

Examples

import Koa from 'koa';
import cors from '@koa/cors';

const app = new Koa();

app.use(cors({
  origin: 'https://app.example.com',
  credentials: true,
  allowHeaders: ['Content-Type', 'Authorization'],
}));

app.use(async (ctx) => {
  ctx.body = { data: 'cross-origin ok' };
});

app.listen(3000);
Output
OPTIONS /  → 204  Access-Control-Allow-Origin: https://app.example.com
GET /      → 200  Access-Control-Allow-Credentials: true
// Dynamic origin based on allowlist
const ALLOWED = new Set(['https://a.com', 'https://b.com']);

app.use(cors({
  origin: (ctx) => ALLOWED.has(ctx.get('Origin')) ? ctx.get('Origin') : false,
}));
Output
(origin https://a.com → reflected; others → no CORS header)

Notes

Mount CORS middleware before route handlers and before body parsers. Setting `credentials: true` requires a specific `origin` (not `"*"`); browsers block credentialed requests with wildcard origin.

See also