Typhoon is a lightweight Rust/WASM frontend framework designed for beginners.
No JavaScript. No heavyweight runtime. Just Rust and the DOM.
Features
Write HTML-like trees directly in Rust. Nested elements, event handlers, attributes — all in one expression.
use_state() gives you fine-grained reactivity. Subscribers fire instantly when values change.
use_local_storage() persists any serialisable value to localStorage automatically.
use_router() maps #/, #/about etc. to render functions — zero config.
use_effect() runs after mount. use_interval() sets up a repeating timer with RAII cleanup.
Built with opt-level = "z", LTO, and wasm-opt. Stays lean so pages load fast.
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);
Roadmap
tp! macro — nested HTML-like treesSignal<T> + use_state()use_local_storage() — JSON persistenceuse_router() — hash-based routinguse_effect() + use_interval()(expr)use_memo() — computed signalscargo add typhoon-core#[typhoon::main] attribute macro