Open-Source Wikis

/

Solid

/

Packages

/

solid-js/web/storage

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                # provideRequestEvent

The 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:

  1. Server-only guard. The function throws if called from a browser-condition build. Calling code typically wraps with if (isServer) { ... }.
  2. 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.
  3. Same Symbol. RequestContext is the same Symbol you would get if you read it from dom-expressions's server export. That keeps provideRequestEvent (Solid layer) and getRequestEvent (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 HTML

Integration 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 in dom-expressions and is re-exported from solid-js/web (server condition). This module is the write half.
  • solid-js/web (server) is the only external import 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 expect solid-js/web/storage to be a server-only module that can pull in node:async_hooks.
  • Cross-runtime support: AsyncLocalStorage is supported on Node, Deno (node:async_hooks polyfill), 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.

solid-js/web/storage – Solid wiki | Factory