CORS Middleware
Type: Reference / Specification
Path: cors/
1. Purpose
The CORS module configures Cross-Origin Resource Sharing middleware on the Hono app. It supports global defaults derived from RestConfig.allowedOrigins, per-route static overrides, and dynamic resolver functions for runtime origin decisions.
1.1 Responsibilities
- Default CORS derivation — Build sensible defaults from
RestConfig.allowedOrigins - Global middleware — Apply a catch-all CORS handler to all routes
- Route-specific rules — Apply per-path overrides or resolver-based CORS before the global handler
- Security boundary — Deny access (empty origin) when resolvers throw errors
1.2 Non-Goals
- Authentication — CORS is a browser security mechanism, not an auth layer
- Request blocking — CORS headers influence browser behavior but do not block server-side requests
2. Architecture
applyCorsConfig accepts RestConfig directly (not ServerConfig).
3. Configuration Flow
3.1 Enabled States
CorsConfig.enabled controls whether CORS middleware is applied:
trueor"default"(default) — CORS middleware is activefalse— No CORS middleware is applied, no CORS headers are set
3.2 Default Options
buildDefaultCorsOptions derives defaults from RestConfig:
Origin resolution when no cors.defaults.origin is specified:
- If
allowedOriginshas entries — request origin is checked against the list, rejected origins get"" - If
allowedOriginsis empty — returns"*"(allow all)
All defaults can be overridden via cors.defaults.
3.3 Application Order
- Route-specific rules (
cors.addCors[]) are applied first as path-scoped middleware - Global CORS (
app.use("*", cors(...))) is applied last as a catch-all
This order matters in Hono: route-specific middleware runs before global middleware for matching paths.
4. Route Rules (CorsRouteRule)
Each rule targets a specific path and can use either static options or a dynamic resolver:
Or with a resolver:
If both options and resolver are present, resolver takes precedence.
5. Resolver Behavior
A CorsResolver function receives the request origin and Hono context, and returns:
The deny-on-error behavior is a security decision: resolver failures never fall through to allow.
6. Key Types
6.1 CorsConfig
6.2 CorsOptions
Compatible with Hono's cors() middleware parameter shape.
6.3 CorsResolver
6.4 CorsRouteRule
7. Constraints
- Hono middleware ordering — The global
app.use("*", cors(...))also fires on routes that have route-specific rules. In practice this means the global handler may overwrite route-specific headers. This is known Hono behavior. - No preflight caching per-route —
maxAgeis set globally. Route-specificmaxAgeoverrides are applied but browser caching behavior may vary.
8. Failure Modes
- Resolver throws — Caught, logged to
console.error, origin set to""(deny) - Empty
allowedOriginswith nocors.defaults.origin— Falls through to"*"(allow all). This is intentional for development convenience but should be restricted in production. enabled: false— No CORS middleware is applied. Browsers will block cross-origin requests entirely.