Request-scoped DI containers in App Router / RSC

Request-scoped DI containers in App Router / RSC

Hi! I’m experimenting with a small TypeScript dependency injection library and recently added a Next.js App Router / React Server Components adapter.

Links:

The main idea is to keep the core DI container framework-agnostic and expose the Next-specific behavior through separate subpath exports:

import { createNextDi } from "di-craft/next/server";
import { hydrate } from "di-craft/next/client";

The model is:

  • create one root container on the server;
  • create a child container per request/render;
  • use React.cache as the request memoization primitive for RSC;
  • keep React/Next out of the core package;
  • avoid moving the DI container to the client;
  • pass only serializable state snapshots from server state entities to client state entities.

So instead of this:

server DI container -> client DI container

it uses this:

server state -> serializable snapshot -> client state

The adapter also has an explicit helper for Route Handlers and Server Actions, where the request container can be disposed after the callback.

The demo covers:

  • Page / RSC request scope;
  • nested Server Components;
  • Route Handler;
  • Server Action;
  • parallel requests;
  • client hydration from a server snapshot.

Demo source:

Note: the demo is intended for a real local Node.js environment or Vercel deployment. StackBlitz/WebContainer environments may fail with current Next.js dev runtime limitations around Turbopack/Webpack fallback and RSC internals.

I’m mostly trying to validate the userland pattern, especially these parts:

  1. Is React.cache the right primitive for request-scoped userland containers in RSC?
  2. Is there any recommended lifecycle/disposal pattern for request-scoped resources after an RSC render?
  3. Does the server state -> serializable snapshot -> client state model fit App Router boundaries well?
  4. For progressive state delivery, should this just lean on Suspense/streaming, or is there a reasonable pattern for partial snapshots?

This is not a request for framework integration. I’d be happy to hear any feedback, corrections, or advice around request lifecycle, disposal, and state snapshots in App Router/RSC.