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, the origin defaults to""(deny). This is intentional, open access must be explicitly configured.
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 (helper pattern):
If both options and resolver are present, resolver takes precedence.
5. Resolver Behavior (Helper Pattern)
Resolvers receive a CorsHelper object pre-loaded with the server's default CORS options. Instead of returning values, the resolver calls setter methods on the helper to override specific settings. If nothing is called, defaults apply.
Helper Methods
If the resolver throws, the request is denied (origin set to ""). Resolver failures never fall through to allow, this is a security decision.
6. Key Types
6.1 CorsConfig
6.2 CorsOptions
Compatible with Hono's cors() middleware parameter shape.
6.3 CorsHelper
Pre-loaded with server defaults. Call methods to override; if nothing is called, defaults apply.
6.4 CorsResolver
Receives the helper as the third parameter. No return value; uses setter methods instead.
6.5 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) enabled: false: No CORS middleware is applied. Browsers will block cross-origin requests entirely.- Empty
allowedOriginswith nocors.defaults.origin: Origin defaults to""(deny). Open access must be explicitly configured via an allowed list or"*".`