Build web UIs in pure Rust

Typhoon is a lightweight Rust/WASM frontend framework designed for beginners.
No JavaScript. No heavyweight runtime. Just Rust and the DOM.

Rust 2021 WASM < 100 KB crates.io MIT
Get started View on GitHub

🧩 tp! macro

Write HTML-like trees directly in Rust. Nested elements, event handlers, attributes — all in one expression.

⚡ Reactive signals

use_state() gives you fine-grained reactivity. Subscribers fire instantly when values change.

💾 Local storage

use_local_storage() persists any serialisable value to localStorage automatically.

🔀 Hash router

use_router() maps #/, #/about etc. to render functions — zero config.

⏱ Effects & timers

use_effect() runs after mount. use_interval() sets up a repeating timer with RAII cleanup.

📦 < 100 KB

Built with opt-level = "z", LTO, and wasm-opt. Stays lean so pages load fast.

🦀 Beginner friendly

No black-box magic. Read the source — it's < 300 lines of straightforward Rust.

Live demo

use typhoon_core::prelude::*;
use wasm_bindgen::prelude::*;

// counter that survives page refresh
let count = use_local_storage("count", 0i32);

let display = tp! {
    p.text(count.get())
     .style("font-size:2rem")
};
let disp_ref = display.clone();
let count_sub = count.clone();
count.subscribe(move || {
    disp_ref.set_text_content(
        Some(&count_sub.get().to_string())
    );
});

let c = count.clone();
let app = tp! {
    div.class("app") {
        h1.text("🌀 Counter")
        button.onclick(move || c.set(c.get() + 1)) { "+" }
    }
};
app.append_child(display.as_ref()).unwrap();
mount(app);
 counter demo