solidjs/solid
solid-js/web/storage
Active contributors: Ryan Carniato
A small entry point that wraps Node's AsyncLocalStorage so that SSR code can attach a request event to the current async context and read it from anywhere down the call stack.
Purpose
When you render Solid on the server, you frequently need access to the active HTTP request — cookies, headers, a per-request cache. Instead of threading a request argument through every component, solid-js/web/storage lets you provide it once at the top of the SSR entry and read it via the global RequestContext symbol from any component or server-only utility.
Directory layout
packages/solid/web/storage/
├── package.json # ./web/storage export selector
├── tsconfig.build.json
├── tsconfig.json
└── src/
└── index.ts # provideRequestEventThe directory only has one source file (src/index.ts, 13 lines). The corresponding bundle is produced by an entry in packages/solid/rollup.config.js.
Key abstractions
| Symbol | Source | Description |
|---|---|---|
provideRequestEvent<T extends RequestEvent, U>(init, cb) |
packages/solid/web/storage/src/index.ts |
Lazily creates an AsyncLocalStorage<T> keyed off the global RequestContext symbol, then runs cb() inside ctx.run(init, cb). |
RequestContext (re-exported from solid-js/web) |
dom-expressions/src/server.js |
The Symbol used to locate the AsyncLocalStorage instance on globalThis. Stable across module instances. |
RequestEvent (re-exported from solid-js/web) |
dom-expressions/src/server.js |
The minimal shape of a request: typically { request: Request, response?: Response, … }. |
How it works
import { AsyncLocalStorage } from 'node:async_hooks';
import { isServer, RequestContext, type RequestEvent } from 'solid-js/web';
export function provideRequestEvent<T extends RequestEvent, U>(
init: T,
cb: () => U
): U {
if (!isServer)
throw new Error('Attempting to use server context in non-server build');
const ctx: AsyncLocalStorage<T> = ((globalThis as any)[RequestContext] =
(globalThis as any)[RequestContext] || new AsyncLocalStorage<T>());
return ctx.run(init, cb);
}Three things to notice:
- Server-only guard. The function throws if called from a browser-condition build. Calling code typically wraps with
if (isServer) { ... }. - Singleton AsyncLocalStorage. The first call allocates the storage on
globalThis[RequestContext]. Subsequent calls reuse the same instance, so multiple module copies (for example, dual-published CJS + ESM bundles in a Node app) end up sharing the same context. - Same Symbol.
RequestContextis the same Symbol you would get if you read it fromdom-expressions's server export. That keepsprovideRequestEvent(Solid layer) andgetRequestEvent(dom-expressions layer) interoperable.
sequenceDiagram
participant Server as SSR entry
participant ALS as AsyncLocalStorage
participant Comp as Component / util
participant DX as dom-expressions
Server->>ALS: provideRequestEvent(req, render)
ALS->>ALS: ctx.run(req, cb)
ALS->>Comp: cb() — async work proceeds
Comp->>DX: getRequestEvent()
DX->>ALS: globalThis[RequestContext].getStore()
ALS-->>DX: req
DX-->>Comp: req
Comp-->>Server: rendered HTMLIntegration points
- This entry point is consumed by SolidStart and similar meta-frameworks that want a single line wrapping the SSR entry:
provideRequestEvent(event, () => renderToStream(App)). - The retrieval side (
getRequestEvent) lives indom-expressionsand is re-exported fromsolid-js/web(server condition). This module is the write half. solid-js/web(server) is the onlyexternalimport in the Rollup config for this entry (packages/solid/rollup.config.js).
Key source files
| File | Purpose |
|---|---|
packages/solid/web/storage/src/index.ts |
The whole implementation — provideRequestEvent. |
packages/solid/web/storage/package.json |
The ./web/storage export selector — only one set of conditions because it is server-only. |
packages/solid/rollup.config.js (entry block for web/storage/src/index.ts) |
Bundle definition: external solid-js/web, output web/storage/dist/storage.js and .cjs. |
Entry points for modification
- Adding new request-scoped helpers: the conventional place is here. Anything that should be read from the active request belongs in this entry rather than
solid-js/web, because consumers expectsolid-js/web/storageto be a server-only module that can pull innode:async_hooks. - Cross-runtime support:
AsyncLocalStorageis supported on Node, Deno (node:async_hookspolyfill), and recent Cloudflare Workers (with the compatibility flag enabled). If you add fallbacks, prefer to detect at runtime rather than at import time so the bundle stays small.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.