Architecture
How Resuma turns Rust components into instantly-interactive HTML without hydration.
LIVE
Resumability pipeline
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 chunksPipeline of one click
- view! expansion — closure → rs2js (in resuma-macros) → HandlerRef in HTML
- SSR — walk View tree, emit data-r-on:* attributes + JSON payload
- 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 / module | Role |
|---|---|
resuma | Single runtime crate — depend on this only |
resuma::core | Signals, View, resumability primitives |
resuma::ssr | HTML rendering + streaming chunks |
resuma::server | axum HTTP, /_resuma/* endpoints |
resuma::flow | FlowApp, pages, loads, submits |
resuma::exec | Resuma OS — workers, queue, scheduler, graphs |
resuma-flow | Ops UI — dashboard, graph widgets (optional crate) |
resuma::router | File-based page scanner |
resuma-macros | view!, #[component], #[load], #[submit] (proc-macros) |
Resumability vs hydration
| Aspect | Classic SSR + hydration | Resuma |
|---|---|---|
| Client after load | Re-run components | Resume handlers only |
| Initial JS | App bundle grows with UI | 907 B loader + ~5 KiB first interaction + lazy chunks |
| Static pages | Often still ship framework JS | Zero client JS |
HTTP endpoints
Core (all apps)
GET /_resuma/runtime.js— client bootstrapPOST /_resuma/action/:name— #[server] RPCPOST /_resuma/submit/:name— #[submit] formsGET /_resuma/handler/:chunk— lazy handler JS
Resuma OS (when exec is enabled)
POST /_resuma/worker/:name— start execution graphPOST /_resuma/queue/:name— durable enqueueGET /_resuma/graph/:id/events— SSE event streamGET /_resuma/status·GET /_resuma/metrics— ops / Prometheus