Getting Started Resumably

Resuma is a resumable Rust web framework — no hydration, no eager JS execution. Components run on the server; a tiny loader resumes interactivity on demand. Resuma Flow adds file-based pages, loads, and submits in one crate — core and full-stack unified.

Examples in this repo

See Examples for all runnable crates and when to use each.

Rust apps run on the server — clone the repo and launch a live example in one command:

Todo (full showcase)

Signals, #[server], #[island], js!, theme — every Resuma feature in one app.

cargo run -p example-todo

Flow demo (full-stack)

Loads, submits, streaming SSR, and deferred chunks.

cargo run -p example-flow-demo

Docs are live at resuma-docs.fly.dev. To hack on the docs site locally: cargo run -p example-website (source in apps/docs-site, not under examples/).

Prerequisites

To build Resuma apps locally, you need:

  • Rust 1.91+ (stable channel via rustup)
  • Node.js 18+ (optional — only to rebuild the JS runtime)
  • Your favorite editor (VS Code + rust-analyzer recommended)

Optionally, read How resumability works before scaffolding.

Install the CLI

From crates.io (recommended):

cargo install resuma

API reference: docs.rs/resuma · docs.rs/resuma-macros

From source while developing the monorepo:

git clone https://github.com/GolfredoPerezFernandez/resuma
cd resuma
cargo install --path crates/resuma --features cli

resuma --help

Create an app using the CLI

Use resuma new or resuma create to scaffold a starter. Pick a template:

basicStatic SSR page · zero client JS · clean starting point
todoSignals · #[server] · #[island] · js! — all Resuma features
# Static page (default)
resuma new my-app
resuma new my-app --template basic

# Full feature showcase
resuma new my-app --template todo

cd my-app

The CLI generates Cargo.toml and src/main.rs.

Start the development server

Inside your project directory. resuma dev installs cargo-watch if needed, rebuilds on save, and refreshes the browser automatically.

resuma dev
    resuma dev --open   # open http://127.0.0.1:3000

Without the CLI, plain Cargo works too:

cargo run

Hello, Resuma

A minimal component with resumable state:

use resuma::prelude::*;

#[component]
fn Hello() -> View {
    let excited = use_signal(false);
    view! {
        <main>
            <h1>"Hello Resuma"</h1>
            <button onClick={ move |_| excited.set(true) }>
                "Click me"
            </button>
        </main>
    }
}

#[tokio::main]
async fn main() -> std::io::Result<()> {
    ResumaApp::new()
        .page("/", || Hello::render(HelloProps::default()))
        .serve(ServeOptions::default())
        .await
}

Add a server action

#[server]
async fn greet(name: String) -> String {
    format!("Hello, {name}!")
}

From a handler, call __resuma.action('greet', [name]) — RPC at POST /_resuma/action/:name.

Project structure

basic / todo — single main.rs (+ security modules for todo). Flow — add src/pages/ (see Project structure).

my-app/                  # resuma new --template todo
├── Cargo.toml
└── src/
    ├── main.rs
    ├── security.rs
    └── todo_store.rs

Next steps