---
title: "Context Storage"
description: "The Hono context storage mechanism leverages Node.js Execution Context AsyncLocalStorage to maintain request-scoped access to the Execution Context instance across asynchronous call boundaries with..."
last_updated: "2026-10-12T08:14:12.769531+00:00"
canonical_url: "https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/traffic-middleware/context-storage"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [src/middleware/context-storage/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts)
- [src/context.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/context.ts)
- [src/jsx/hooks/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/jsx/hooks/index.ts)
- [src/middleware/request-id/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/request-id/index.ts)
- [src/jsx/context.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/jsx/context.ts)
- [src/helper/route/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts)
- [src/jsx/streaming.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/jsx/streaming.ts)
- [src/middleware/language/language.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/language/language.ts)
- [src/middleware/jsx-renderer/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/jsx-renderer/index.ts)
- [src/jsx/dom/intrinsic-element/components.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/jsx/dom/intrinsic-element/components.ts)
- [src/middleware/cache/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/cache/index.ts)
- [src/middleware/timing/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/timing/index.ts)
- [src/jsx/dom/context.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/jsx/dom/context.ts)
- [src/middleware/timing/timing.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/timing/timing.ts)
- [src/middleware/logger/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/logger/index.ts)
- [src/helper/cookie/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/cookie/index.ts)
- [src/middleware/request-id/request-id.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/request-id/request-id.ts)
- [src/helper/streaming/stream.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/streaming/stream.ts)
- [src/adapter/cloudflare-pages/handler.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/adapter/cloudflare-pages/handler.ts)
- [src/middleware/language/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/language/index.ts)
- [src/adapter/bun/server.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/adapter/bun/server.ts)
- [src/adapter/lambda-edge/conninfo.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/adapter/lambda-edge/conninfo.ts)
- [runtime-tests/workerd/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/runtime-tests/workerd/index.ts)
- [src/hono-base.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/hono-base.ts)
- [src/helper/adapter/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/adapter/index.ts)
- [src/request.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/request.ts)
- [src/adapter/aws-lambda/types.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/adapter/aws-lambda/types.ts)
- [src/middleware/jwt/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/jwt/index.ts)
- [src/adapter/netlify/handler.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/adapter/netlify/handler.ts)
- [src/utils/concurrent.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/concurrent.ts)
</details>

## Overview

The Hono context storage mechanism leverages Node.js [Execution Context](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/core-engine/execution-context) `AsyncLocalStorage` to maintain request-scoped access to the [Execution Context](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/core-engine/execution-context) instance across asynchronous call boundaries without explicitly passing parameters through every function. By integrating with middleware execution flow, it binds incoming requests to an asynchronous store so that nested handlers, utility functions, and background services can retrieve active request details on demand. This architecture eliminates the need for manual context threading in deeply nested business logic while ensuring proper isolation between concurrent requests in supported runtimes.

Sources: [src/middleware/context-storage/index.ts:6-11](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L6-L11), [src/middleware/context-storage/index.ts:43-47](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L43-L47)

## AsyncLocalStorage Architecture

### Storage Mechanism

The underlying storage relies on Node.js `AsyncLocalStorage` initialized as a module-level constant instance typed against the Hono [Execution Context](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/core-engine/execution-context). This storage container maintains request isolation by capturing asynchronous execution contexts across disparate call frames.

```typescript
import { AsyncLocalStorage } from 'node:async_hooks'
import type { Context } from '../../context'
import type { Env, MiddlewareHandler } from '../../types'

const asyncLocalStorage = new AsyncLocalStorage<Context>()
```
Sources: [src/middleware/context-storage/index.ts:6-10](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L6-L10)

> [!NOTE]
> `asyncLocalStorage` is a single module-scoped singleton instance shared across all requests handled by the middleware, relying on Node's async execution tracking to segregate concurrent stores.

Sources: [src/middleware/context-storage/index.ts:6-10](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L6-L10)

### Lifecycle Integration

The middleware wraps downstream execution by passing the current `Context` instance into the `asyncLocalStorage.run` method alongside the `next` dispatch function. This anchors the active [Execution Context](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/core-engine/execution-context) to the asynchronous boundary for the duration of all subsequent middleware and route handlers.

```typescript
export const contextStorage = (): MiddlewareHandler => {
  return async function contextStorage(c, next) {
    await asyncLocalStorage.run(c, next)
  }
}
```
Sources: [src/middleware/context-storage/index.ts:43-47](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L43-L47)

> [!WARNING]
> Any asynchronous operations executed outside the scope established by `asyncLocalStorage.run` will lose access to the bound `Context`, resulting in undefined stores when calling retrieval functions.

Sources: [src/middleware/context-storage/index.ts:43-47](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L43-L47)

## Context Storage Middleware

### Middleware Initialization

The `contextStorage` factory function returns a `MiddlewareHandler` closure designed to intercept incoming request dispatches. When invoked, it yields an asynchronous middleware function that establishes the request boundary before invoking downstream handlers.

```typescript
export const contextStorage = (): MiddlewareHandler => {
  return async function contextStorage(c, next) {
    await asyncLocalStorage.run(c, next)
  }
}
```
Sources: [src/middleware/context-storage/index.ts:43-47](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L43-L47)

### Context Binding During Dispatch

During the request dispatch cycle, the middleware binds the active `Context` instance (`c`) to the module-scoped `AsyncLocalStorage` instance by executing `asyncLocalStorage.run(c, next)`. This wraps the remaining middleware chain and route handlers (`next`) within a tracked asynchronous execution frame.

```typescript
return async function contextStorage(c, next) {
  await asyncLocalStorage.run(c, next)
}
```
Sources: [src/middleware/context-storage/index.ts:44-46](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L44-L46)

> [!NOTE]
> The `next` function passed into `asyncLocalStorage.run` ensures that all subsequent asynchronous yields, promises, and downstream handlers inherit the bound `Context` transparently.

Sources: [src/middleware/context-storage/index.ts:44-46](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L44-L46)

## Accessing Context Outside Handlers

### Retrieval Functions

The public API exports two functions for accessing the active request [Execution Context](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/core-engine/execution-context) outside of standard route handlers: `tryGetContext` and `getContext`. Both functions accept an optional generic type parameter `E` extending `Env` to type-check environment bindings and variables. `tryGetContext` queries the underlying `AsyncLocalStorage` store directly, returning the active `Context<E>` instance or `undefined` if invoked outside an active request scope.

```typescript
export const tryGetContext = <E extends Env = Env>(): Context<E> | undefined => {
  return asyncLocalStorage.getStore() as Context<E> | undefined
}
```
Sources: [src/middleware/context-storage/index.ts:49-51](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L51)

> [!TIP]
> Use `tryGetContext` in utility functions or shared modules that may execute both within and outside of HTTP request lifecycles, allowing graceful handling of missing context states without throwing exceptions.

Sources: [src/middleware/context-storage/index.ts:49-51](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L49-L51)

### Error Handling and Enforcement

The `getContext` function wraps `tryGetContext` with a validation check, throwing an explicit error when no request context is present in the asynchronous store. This provides strict guarantees for service functions or helpers that depend unconditionally on active request bindings.

```typescript
export const getContext = <E extends Env = Env>(): Context<E> => {
  const context = tryGetContext<E>()
  if (!context) {
    throw new Error('Context is not available')
  }
  return context
}
```
Sources: [src/middleware/context-storage/index.ts:53-59](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L53-L59)

> [!WARNING]
> Calling `getContext` outside of a request scope initialized by the middleware throws a `Context is not available` error, halting execution.

Sources: [src/middleware/context-storage/index.ts:55-57](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L55-L57)

## Runtime Compatibility and Constraints

### Node.js and Async Context Foundation

The underlying storage mechanism relies on `AsyncLocalStorage` imported directly from the Node.js built-in `node:async_hooks` module. This restricts native context propagation support to runtimes that fully implement Node.js asynchronous hook APIs or provide compatible runtime shims.

```typescript
import { AsyncLocalStorage } from 'node:async_hooks'
import type { Context } from '../../context'
import type { Env, MiddlewareHandler } from '../../types'

const asyncLocalStorage = new AsyncLocalStorage<Context>()
```
Sources: [src/middleware/context-storage/index.ts:6-10](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L6-L10)

> [!NOTE]
> Modern JavaScript runtimes such as Node.js, Bun, and Deno natively support `AsyncLocalStorage`, ensuring seamless execution of the context storage middleware across these environments.

Sources: [src/middleware/context-storage/index.ts:6-10](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L6-L10)

### Isolation Guarantees and Error Boundaries

Because `asyncLocalStorage` is instantiated as a module-scoped constant, concurrent requests handled by the server maintain strict state isolation. Each asynchronous execution frame created by `asyncLocalStorage.run` encapsulates its own `Context` reference, preventing cross-request data leakage even during concurrent asynchronous yields.

```typescript
const asyncLocalStorage = new AsyncLocalStorage<Context>()
```
Sources: [src/middleware/context-storage/index.ts:10-10](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L10-L10)

> [!CAUTION]
> Spawning independent asynchronous tasks or background promises using native `setTimeout` or unawaited promise chains outside of the tracked middleware boundary will detach execution from the active store, causing `tryGetContext` to return `undefined` and `getContext` to throw an unhandled error.

Sources: [src/middleware/context-storage/index.ts:43-58](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/middleware/context-storage/index.ts#L43-L58)

## Related

- [Execution Context](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/core-engine/execution-context)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/llms.txt) for all pages in this wiki.
