Reactivity internals

How Resuma differs from hydration frameworks: components run once on the server; the browser resumes signals and lazy handler chunks.

Lifecycle overview

  1. SSR render#[component] functions build a View tree.
  2. Capture — signals, handlers, contexts, and effects are recorded in RenderContext.
  3. SerializeResumePayload is embedded in <script type=\"resuma/state\">.
  4. Resume — runtime reconstructs signal cells and binds data-r-bind:*.
  5. Interact — first click fetches /_resuma/handler/{Component}.js and runs the handler.

Signal lifecycle

// Server: allocate id + initial value
let n = use_signal(0);

// Serialized: { id: "s1", value: 0 }
// Client: SignalCell with .set/.update + subscribers on DOM nodes

// Handler closure captures signal id — not the Rust Signal handle
onClick={move |_| n.update(|v| *v += 1)}

Effects

  • use_effect / use_computed — SSR dependency tracking only.
  • effect! / computed! — rs2js translates to client-replayable JS.
  • debounce! — debounced client effect registration.

No VDOM diff

Like Leptos/Solid, updates target DOM nodes bound to signals. Unlike Leptos CSR/WASM, Resuma never re-runs the component tree in the browser — handlers patch the DOM directly.

Further reading