Orientation Arc
Routing Algorithms
Rendering and JSX
Runtime Adapters
Middleware Ecosystem
Developer Helpers
System Utilities
The following files were used as context for generating this wiki page:
Utility middleware in the Hono framework serves as the foundational layer for cross-cutting concerns, abstracting repetitive HTTP request/response tasks into composable, reusable units. By providing standardized implementations for security headers, request validation, language detection, and cloud platform adapters, these components allow developers to maintain clean, focused route handlers. This design follows the Hono principle of keeping the core framework "tiny" while offering powerful, optional functionality via a robust middleware pattern.
These components function by hooking into the Hono request-handling pipeline. Whether acting as a perimeter security layer (like secureHeaders), a data sanitization layer (validator), or a contextual enrichment layer (languageDetector), each utility effectively transforms the incoming Context or prepares the Response headers. This architecture ensures that platform-specific complexities—such as AWS Lambda event normalization or Content Security Policy generation—are handled uniformly, significantly reducing boilerplate code in business logic.
The utility subsystem leverages Hono's Context (src/context.ts) as a shared communication bus. Middleware can query request state, set internal variables via ctx.set(), and append headers before the request reaches the final handler. The flow is strictly ordered, enabling early-return scenarios (like the validator throwing an HTTPException) and late-stage modifications (like secureHeaders applying modifications to the res object after next() has finished).
The validator subsystem provides a mechanism to verify incoming data against a target (e.g., json, form, query). It operates as a MiddlewareHandler that performs schema checks and data type enforcement before the application code is executed.
When a validator is defined, it maps a specific request target (e.g., json) to a validation function. If the content type check fails (e.g., the Content-Type header is not application/json), the middleware silently skips further validation for that target. However, if the data is present and correctly typed, the function processes the data.
Caution
The validator throws an HTTPException(400) when it encounters malformed JSON or invalid FormData. If you are chaining multiple validators, ensure your error-handling middleware is configured to catch these status codes.
// Example: Validating a JSON payload
app.post(
'/user',
validator('json', (value, c) => {
if (!value.name) return c.json({ error: 'Name required' }, 400)
return value
}),
(c) => c.json({ status: 'ok' })
)Sources: src/validator/validator.ts:46-138
The secureHeaders middleware enforces web security by injecting standard security headers (e.g., Content-Security-Policy, X-Content-Type-Options) into every response. The middleware initializes its state based on DEFAULT_OPTIONS, which are merged with any user-provided overrides.
A key feature is the dynamic generation of CSP nonces. The NONCE handler checks the current Context for an existing secureHeadersNonce. If absent, it generates a cryptographically secure random value using crypto.getRandomValues(new Uint8Array(16)), stores it in the context for reuse, and returns it. This ensures that the same nonce is available for both the CSP header and the HTML templates throughout the request lifecycle.
Sources: src/middleware/secure-headers/secure-headers.ts:131-145
The languageDetector middleware identifies the preferred locale of a client by iterating through a defined order of strategies: querystring, cookie, header, and path.
detectLanguage function loops through the enabled detectors. As soon as one returns a non-null language string, it stops searching.normalizeLanguage, which compares it against supportedLanguages. It supports RFC 4647-style progressive truncation (e.g., matching en-US to en).['cookie']), the cacheLanguage function is called to set a persistent cookie on the response.Sources: src/middleware/language/language.ts:229-258
The aws-lambda adapter abstracts multiple AWS event sources (API Gateway v1/v2, ALB, Lattice) into a single, unified Hono Request object. The adapter uses a processor pattern to decouple platform-specific event normalization from the Hono application logic.
handle(): The entry point that captures the event and invokes getProcessor(event).processor.createRequest(event): Normalizes query parameters, headers, and body (decoding base64 if needed).app.fetch(): Executes the Hono app with the unified Request and cloud-platform context.processor.createResult(event, res): Transforms the standard Response back into the format expected by the specific AWS service (e.g., handling binary encoding).Sources: src/adapter/aws-lambda/handler.ts:239-276
The getProcessor function acts as a factory, selecting the appropriate logic based on the shape of the incoming LambdaEvent.
Sources: src/adapter/aws-lambda/handler.ts:639-651
Note
The factory prioritizes ALB and V2 events specifically; if neither matches, it defaults to v1Processor. Ensure that the isProxyEventALB condition is unique for your infrastructure.
The adapter must decide whether to base64-encode the response body before returning it to AWS. This is handled by defaultIsContentTypeBinary, which returns true if the content type is not text/plain, text/html, etc.
export const defaultIsContentTypeBinary = (contentType: string): boolean => {
return !/^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/.test(
contentType
)
}Sources: src/adapter/aws-lambda/handler.ts:677-681
Sources: src/adapter/aws-lambda/handler.ts:278-402