Architecture

How Resuma turns Rust components into instantly-interactive HTML without hydration.

LIVE

Resumability pipeline

1. SSR render

The resumability promise

Traditional SSR: render on server → hydrate on client (re-run all components). Resuma: render once → serialize state → client resumes only what the user touches.

Server (Rust)  ──HTML + payload──►  Browser
render components              parse resuma/state + loader.js (907 B gzip)
serialize signals              first click → core.js (~4 KiB gzip)
                               lazy-import handler chunks

Pipeline of one click

  1. view! expansion — closure → rs2js (in resuma-macros) → HandlerRef in HTML
  2. SSR — walk View tree, emit data-r-on:* attributes + JSON payload
  3. Runtime — document listener, lazy fetch handler chunk, update signals

Payload format

<script type="resuma/state" id="resuma-state">
{"signals":[...],"handlers":{},"lazy_chunks":["Counter"],"islands":[],"actions":[]}
</script>
<script type="module" src="/_resuma/loader.js"></script>

Component boundaries

Each #[component] emits <resuma-boundary data-r-chunk="Counter"> for viewport prefetch. Handler JS loads from /_resuma/handler/Counter.js — not inlined in the payload.

Crates

Crate / moduleRole
resumaSingle runtime crate — depend on this only
resuma::coreSignals, View, resumability primitives
resuma::ssrHTML rendering + streaming chunks
resuma::serveraxum HTTP, /_resuma/* endpoints
resuma::flowFlowApp, pages, loads, submits
resuma::execResuma OS — workers, queue, scheduler, graphs
resuma-flowOps UI — dashboard, graph widgets (optional crate)
resuma::routerFile-based page scanner
resuma-macrosview!, #[component], #[load], #[submit] (proc-macros)

Resumability vs hydration

AspectClassic SSR + hydrationResuma
Client after loadRe-run componentsResume handlers only
Initial JSApp bundle grows with UI907 B loader + ~5 KiB first interaction + lazy chunks
Static pagesOften still ship framework JSZero client JS

HTTP endpoints

Core (all apps)

  • GET /_resuma/runtime.js — client bootstrap
  • POST /_resuma/action/:name — #[server] RPC
  • POST /_resuma/submit/:name — #[submit] forms
  • GET /_resuma/handler/:chunk — lazy handler JS

Resuma OS (when exec is enabled)

Full route list →

  • POST /_resuma/worker/:name — start execution graph
  • POST /_resuma/queue/:name — durable enqueue
  • GET /_resuma/graph/:id/events — SSE event stream
  • GET /_resuma/status · GET /_resuma/metrics — ops / Prometheus