Skip to content
Persist
Esc
navigateopen⌘Jpreview

Writing a framework adapter

Bridge HydrationSignal into your UI framework — same shape as the shipped React, Preact, Solid, Angular, Vue, Lit, Alpine, and Svelte adapters.

The React hook is ~20 lines over HydrationSignal — every adapter is that shape. Preact, Solid, Angular, Vue, Lit, Alpine, and Svelte ship the same contract (full text on HydrationSignal’s JSDoc).

Subscribe returns an idempotent unsubscribe; each call is an independent subscription. No initial notification and no payload — pull isHydrated() after attach and on every notification. Transitions while detached aren’t replayed (re-read recovers). Render hydrated: true on the server; null signal = no persistence = hydrated.

import type { HydrationSignal } from "@stainless-code/persist";

// The shipped `./frameworks/svelte` adapter, in full — every adapter is this shape:
export function hydratedRune(signal: HydrationSignal | null) {
  if (!signal)
    return {
      get current() {
        return true;
      },
    };
  const subscribe = createSubscriber((update) =>
    signal.subscribeHydrated(update),
  );
  return {
    get current() {
      subscribe();
      return signal.isHydrated();
    },
  };
}

Last updated on July 20, 2026

Was this page helpful?