v1.2.0 · Rust web framework

The lightest path to instant interactivity in Rust

907 bytes to resume. Zero bytes on static pages.

Resuma renders your UI once on the server, serialises signal state into HTML, and lazy-loads only the handlers you touch. No WASM hydration. No component re-execution. Full-stack Flow, server actions, and Resuma OS — one crate.

cargo install resuma · resuma new my-app --template todo · no Node.js for app development

what ships (gzip)
Static page0 B JS
Interactive page — loader907 B
First click — handler chunk5.08 KiB
Next.js counter (default scaffold)142 KiB

156× smaller initial payload than a default Next.js app — measured on the same counter UX.

907 Bloader (gzip)
0 Bstatic pages
5.08 KiBfirst interaction
~3 KiBruntime core
1cargo dependency

Zero-cost static

Marketing pages ship no JavaScript

Docs, blogs, and landing sections without signals or handlers compile to pure HTML. No runtime. No hydration tax. Deploy to the edge and forget about bundle budgets.

Static vs interactive pages →

Payload anatomy

Every byte has a job

Hydration frameworks ship the whole app up front. Resuma ships HTML plus a resumability payload — handlers and core load only when needed.

SSR HTML + signal stateServer

View tree, data-r-on:* hooks, and <script type="resuma/state"> — ready before any JS runs.

Loader907 B gzip

Bootstraps signals from the serialised payload. Enough for static-looking pages to feel alive.

Core runtime~3 KiB gzip

Fine-grained DOM updates, Show/For, effects — fetched on first interaction or prefetch.

Handler chunksPer component

onClick and friends live in /_resuma/handler/{Component}.js — pay only for what users touch.

Measured

Counter page — initial load (gzip)

Same UX everywhere: SSR heading + one increment button. Bar width is relative to Next.js (142 KiB). Full methodology →

Resuma907 B
Qwik1.96 KiB
SolidStart16.75 KiB
SvelteKit27.71 KiB
React (Vite)57.99 KiB
Leptos79.02 KiB
Next.js142.43 KiB
FrameworkInitial loadFirst interactionStatic page
Resuma907 B5.08 KiB0 B
Leptos79.02 KiB79.02 KiB
Next.js142.43 KiB142.43 KiB
React (Vite)57.99 KiB57.99 KiB
Astro57.76 KiB57.76 KiB
SvelteKit27.71 KiB27.71 KiB
Qwik1.96 KiB22.32 KiB
SolidStart16.75 KiB16.75 KiB
templ + HTMX16.21 KiB16.21 KiB

Hydration frameworks load the same JS on page load — initial and first click match. Resuma static pages ship 0 B client JS. node benchmark/run.mjs

Try it in the docs

Live demos — inside the documentation

Interactive examples run on every docs page: workers, signals, forms, and server functions. The homepage stays lean — open a guide and click.

Positioning

Resumability, not hydration

Three ways to ship interactive UI after the first paint.

Qwik

Resumable JS — tiny preloader, lazy chunks on interaction. Closest mental model to Resuma.

Leptos

Rust SSR + WASM hydration and optional islands.

Resuma

Rust SSR + resumability + lazy JS handlers — no WASM by default.

Performance model

Interactive from the first click

The client never re-runs your component tree. State and handlers are already in the HTML.

Ultralight by design

907 B loader, ~3 KiB core, per-handler chunks — not a monolithic client bundle.

🦀

Full Rust stack

#[server] RPC, #[submit] forms, and #[load] data — axum-native, no adapter boilerplate.

📋

Progressive enhancement

<Form submit> works as plain HTML POST before JS loads; runtime enhances in place.

🧩

Resumable by default

Every #[component] is a lazy boundary. Handlers externalise to /_resuma/handler/{Component}.js.

Under the hood

How does it work?

One SSR pass. One resumability payload. Lazy execution on the client.

1

SSR renders once

Rust walks the View tree, emits HTML + data-r-on:* attributes, and serialises signals into <script type="resuma/state">.

2

Payload travels light

Handler sources move to lazy chunks. computed! / effect! / debounce! replay on the client via rs2js.

3

Browser resumes

Loader bootstraps signals. Core loads on first interaction. Handlers fetch on demand — or prefetch in viewport.

Components

Write UI once — on the server

view! with JSX-like syntax, fine-grained signals, and onClick handlers that compile to lazy JavaScript.

  • signal for reactive state
  • computed! / effect! for client replay
  • #[component] props builder generated for you
Component guide →
#[component]
fn Counter() {
    let count = signal(0);
    view! {
        <button onClick={count.update(|c| *c += 1)}>
            "Count: " {count}
        </button>
    }
}
// Handler lazy-loads from /_resuma/handler/Counter.js

Resuma OS

Durable workers — self-hosted

#[worker] functions, disk-backed queues, cron scheduler, and an ops dashboard. No Redis, no external orchestrator — same binary as your app.

  • Execution graphs with SSE event streams
  • Pause, resume, cancel from the Flow UI
  • Queue recovery and checkpointed state
Run the live worker demo →
#[worker(intent = "enrich page")]
async fn enrich(input: Input, ctx: WorkerContext) -> Result<Value> {
    ctx.log("fetching");
    let page = ctx.tool("fetch", json!({ "url": input.url })).await?;
    ctx.progress(50);
    let summary = ctx.tool("ai", json!({
        "prompt": "Extract key facts",
        "data": page
    })).await?;
    Ok(summary)
}

Why Resuma?

Everything you need for modern SSR

Resumable SSR in Rust — one install, progressive enhancement, full-stack Flow when you need it.

🌊

Resuma Flow

File-based pages, #[load], #[submit], layouts, middleware — built into the same crate.

📄

Static export

resuma build --static-export scaffolds HTML from src/pages/ for edge-friendly deploys.

🔧

Dev experience

resuma dev with HMR WebSocket, resuma new templates (basic, todo, flow, production).

🔗

JS bridge

view! translates Rust closures via rs2js. js!{} for escape hatches when you need raw client code.

🏝️

Islands (optional)

#[island(load = "visible")] for heavy widgets — most UI only needs #[component].

🛡️

Security built in

Crypto CSRF, security headers, rate limits — see examples/todo for production patterns.

One package

Resuma¹ + Flow²

Two layers, one dependency. Core stays stable; Flow adds routing, data loading, and forms.

RESUMA¹ — CORE

Components & resumability

  • view!, #[component], signal
  • computed! / effect! / debounce!
  • #[server], ResumaApp, ~3KB runtime
+

FLOW² — FULL-STACK

Pages, loads & submits

  • FlowApp, src/pages/, #[layout]
  • #[load], #[submit], #[middleware]
  • Streaming SSR, cache headers

AI assistants

Build faster with Cursor, Codex, or Gemini

Install the Resuma agent skill in one command — reactive view! rules, Flow patterns, server actions, and debugging checklists built in.

resuma install skill

AI assistant guide →

Integrations

Database, auth, and tooling

Integration guides for SQLx, Turso, auth, validation, i18n, and E2E testing.

All integrations · Search docs

Start building in 60 seconds

Install the CLI, scaffold a project, and ship instantly-interactive Rust UI — ultralight by default.

Read the tutorial
cargo install resuma && resuma new my-app --template todo