π Resuma
The first Rust web framework with SSR + Resumability + Islands + Server Actions + a friendly JS Bridge.
Zero hydration, true resumability, native islands, automatic RustβJS handler compilation.
Install: cargo install resuma Β· Docs: resuma-docs.fly.dev Β· API: docs.rs/resuma Β· Repo: GitHub
What is this?
Resuma is a from-scratch Rust framework for building modern web apps with resumability instead of hydration:
Resumability vs hydration
| Aspect | Classic SSR + hydration | Resuma |
|---|---|---|
| Client work after load | Re-run components to attach listeners | Resume serialized state and handlers |
| Initial JS | Grows with app size | ~3KB runtime + lazy chunks |
| Interactive boundaries | Often manual | First-class #[island] |
| Server RPC | Custom wiring | #[server] async fn + built-in endpoint |
| Handler code on client | Ship framework runtime + app logic | Compile handlers to small JS via rs2js |
| Templates | Varies | JSX-like view!{} β no extra sigils |
The mental model: components only run on the server. The browser never re-executes them. Instead, the SSR pass serialises every signal, handler reference and island into the HTML, and the tiny client runtime resumes execution lazily β exactly when the user clicks something.
Hello, Resuma
use *;
async
That single click handler is automatically translated to JavaScript by resuma-macros (rs2js), lazy-loaded on first interaction, and runs against the resumed signal state. No hydration, no re-execution, no WASM bundle.
Server actions
async
#[server] registers an RPC endpoint at /_resuma/action/search. The handler is dispatched there transparently.
Islands
Mark any component with #[island] and Resuma will package its handlers into an isolated chunk that ships only when the island scrolls into view (or immediately, configurable).
Resuma Flow (full-stack layer)
One crate β resuma includes core + Flow in a single dependency.
| Resuma Flow | Purpose |
|---|---|
FlowApp |
App builder with page registry |
#[load] |
Server data before render |
#[submit] |
Form mutations |
src/pages/ |
File-based pages |
See docs/PACKAGE.md and docs/FLOW.md.
Live docs site: https://resuma-docs.fly.dev Β· or cargo run -p example-website β http://127.0.0.1:3000
Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β resuma crate (v0.2) β
β β
β core βββΊ ssr βββΊ server (axum) β
β β GET /_resuma/runtime.js β
β β POST /_resuma/action/:name β
β ββββΊ flow + router (pages, loads, submits) β
β β
β resuma-macros (separate crate) β
β view! / #[component] / rs2js β JS handlers β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HTTP
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Browser (~3KB) β
β parse resuma/state Β· delegate events Β· lazy handlers β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
See docs/ARCHITECTURE.md for a deep dive.
Security: docs/SECURITY.md β CSRF, headers, rate limits, production checklist.
Backend patterns: docs/BACKEND.md β live in examples/todo.
All docs: docs/README.md Β· cargo run -p example-website
Publishing: docs/PUBLISHING.md β crates.io release checklist
Project layout
Resuma/
βββ crates/
β βββ resuma/ # single runtime crate (core, ssr, server, flow, cli)
β βββ resuma-macros/ # proc-macros + rs2js (required separate crate)
βββ runtime/ # TypeScript source for the ~3KB client runtime
βββ examples/
βββ counter/
βββ todo/
βββ flow-demo/
βββ flow-pages/
βββ website/ # docs site
Docs: docs/README.md Β· live site: cargo run -p example-website
Getting started
Pre-requisites: Rust 1.91+ (rustup).
Install from crates.io (recommended)
- Crate: crates.io/crates/resuma
- API docs: docs.rs/resuma/0.2.3
- Proc-macros: docs.rs/resuma-macros/0.2.3
Library only (no CLI binary):
[]
= { = "0.2", = false }
= { = "1", = ["full"] }
From source (development)
# Examples
What works in v0.2
β
Signal<T>, use_signal, use_effect, use_computed
β
view!{} macro with JSX-like syntax (no $ noise)
β
#[component] with auto-generated props builder
β
#[server] async actions with JSON-RPC endpoint
β
#[island] interactive component boundary
β
js!{} escape hatch for raw JS handlers
β
Rust β JS compiler for common handler patterns
β
SSR with resumability payload embedded in HTML
β
~3KB client runtime (lazy event delegation + signals + RPC)
β
axum-based server with built-in /_resuma/* routes
β
File-based routing scanner (src/routes/[id].rs β /users/:id)
β
resuma CLI: new, dev, build, routes
Roadmap (v0.3+)
- Hot Module Reload via
resumaCLI + websocket bridge - Build-time pre-rendering for static sites
- Partial pre-rendering (PPR) β server shell + dynamic islands
-
#[island(load = "visible")]lazy load policies - Devtools extension for resumability payload inspection
- First-class TypeScript bindings for
js!{}blocks - WASM-backed islands for compute-heavy code (opt-in)
Already shipped in v0.2: single-crate layout, streaming SSR (Flow), layouts, file-based routing, security defaults, crates.io publish.
Why "Resuma"?
Spanish for both resumes (continues) and summary β fitting because the framework's superpower is resuming execution from a serialised summary of the server-side render.
License
MIT OR Apache-2.0