CORS Middleware
cors() brings fine-grained CORS control to bunway while keeping everything Bun-native. The middleware examines the incoming Origin/Access-Control headers, decides whether to allow the request, and records headers so the router can merge them even when you return a raw Response object.
Basic usage
import { cors } from "bunway";
app.use(cors()); // wildcard
app.use(cors({ origin: true })); // reflect request origin
app.use(cors({ origin: "https://app.example.com" }));Set credentials: true to allow cookies/authorization headers—bunway automatically prevents * when credentials are enabled by reflecting the incoming origin instead.
app.use(cors({ origin: true, credentials: true }));Credentials
When credentials: true, bunway automatically reflects the request origin instead of using *. Ensure your allow list covers every origin that should receive credentialed responses.
Allow list patterns
string– match exact originRegExp– pattern match(origin, ctx) => string | false– custom logic (return the origin to allow,falseto block)- Arrays combine multiple strings/regexes
app.use(
cors({
origin: (origin) => (origin?.startsWith("http://localhost") ? origin : false),
allowPrivateNetwork: true,
})
);Preflight requests
Preflight (OPTIONS) requests are answered automatically with:
Access-Control-Allow-OriginAccess-Control-Allow-Methods(customizable viamethodsoption)Access-Control-Allow-Headers(explicit list or echo request header)Access-Control-Allow-Credentialswhencredentials: trueAccess-Control-Max-Age(default 600 seconds)Access-Control-Allow-Private-NetworkwhenallowPrivateNetwork: true
The middleware also ensures the proper Vary headers (Origin, Access-Control-Request-*) are set to keep caches honest.
Header merging
All generated headers are stored in ctx.req.locals.__corsHeaders. bunway’s router finalizer merges these onto the final Response, even if your handler returns a native Response object:
app.get("/raw", () => new Response("raw", { status: 202 }));Options reference
CORS Options reference
origin:"*"|true|string|RegExp|(string \| RegExp)[]|(origin, ctx) => string \| false- Decide which origins are allowed. Returning
falseblocks the request; whencredentials: true, bunWay reflects the approved origin instead of"*".
- Decide which origins are allowed. Returning
credentials:boolean(defaultfalse)- Allow credentialed requests. bunWay automatically prevents
"*"when enabled.
- Allow credentialed requests. bunWay automatically prevents
methods:string[](default['GET','HEAD','PUT','PATCH','POST','DELETE','OPTIONS'])- Whitelist methods used in preflight responses.
allowedHeaders:string[]- Force a specific allow-list instead of echoing
Access-Control-Request-Headers.
- Force a specific allow-list instead of echoing
exposedHeaders:string[]- Populate
Access-Control-Expose-Headers.
- Populate
maxAge:number(default600)- Cache duration (seconds) for successful preflight responses.
allowPrivateNetwork:boolean(defaultfalse)- Opt into
Access-Control-Allow-Private-Network.
- Opt into
Recommendations
- Reflect (
origin: true) when you need credentials. - Keep the allow-list tight in production—prefer regex/string arrays over wildcards.
Production allow list
Audit CORS settings regularly. Accidentally allowing * with credentials or forgetting to restrict origins can expose sensitive endpoints.
- Combine with
errorHandler()to log disallowed origins or unexpected headers.
For type details see CORSOptions in the API Reference.