fusor takes a direct approach to building reactive web applications: write your HTML templates as HTML files, keep your state and logic in Rust, and let the compiler verify that every binding between them is valid. No macros swallowing your markup, no JSX-like abstractions, just HTML and Rust talking to each other through a small set of declarative directives.
The Core Idea
Most Rust-to-browser frameworks blur the boundary between markup and code. fusor keeps it sharp. Templates live in `.html` files, styled with regular CSS, and contain the elements, classes, labels, and forms you would write by hand. Rust values appear inside double-brace bindings or as attributes like `on:click`. The compiler checks every expression in those templates against the corresponding Rust module before anything ships to the browser.
This separation means you design your UI the way you already think about HTML, then reach for Rust when you need state, logic, or event handling. There is no template DSL to learn and no build-step preprocessor transforming your markup into something unrecognizable.
Four Binding Mechanisms
fusor connects the two sides of a component through four primitives. The `rust:component` attribute names the Rust struct that backs a template; its fields become reactive state and its methods become the behavior users trigger. Double-brace bindings, written as `{{ expression }}`, render a Rust value as text or an HTML attribute and automatically update whenever the signals those expressions read change.
Event listeners and two-way bindings use the `on:click` and `bind:value` syntax to run Rust when an interaction fires or to keep an input field synchronized with a signal. Finally, the `template!(…)` macro connects a Rust module to its HTML file so the compiler can verify both sides together. Each module gets its own component, and components compose inside a parent `
Fine-Grained Reactivity Without a Virtual DOM
fusor compiles Rust to WebAssembly and runs it directly in the browser. There is no virtual DOM diffing. Instead, each binding tracks the specific signals it reads. When a signal changes, only the bindings that depend on it re-run; the rest of the component stays untouched.
This model means updates are predictable and minimal by construction. A counter component increments a number and only the text node displaying that number refreshes. A live-search input filters a list and only the list re-renders. The framework does not need a reconciliation algorithm because it tracks dependencies at the signal level from the start.
Component Lifecycle and Async Handling
Listeners, effects, and network requests belong to the component that created them and stop automatically when that component is removed from the page. This ownership model prevents common leaks: a fetch initiated in a component does not fire callbacks after the component is gone.
For data that arrives asynchronously, fusor provides an `
Getting Started
Creating a new fusor project is a single command. `fusor new my-app` generates a `Cargo.toml`, a `build.rs`, and a `src/lib.rs`. Additional component modules are declared in that same file. Running `fusor dev` starts a local development server and opens the app in the browser. The starter template includes a working example component split between an HTML file and a Rust file.
Building with fusor requires Rust 1.85 or newer. The framework is open source under the MIT license and available on GitHub at fusor-rs/fusor.
Where It Fits
The Rust-to-browser space already includes established frameworks like Yew, Leptos, Dioxus, and Sycamore, each with its own approach to reactivity and templating. fusor distinguishes itself by insisting on plain HTML files as templates and a compiler-enforced contract between markup and Rust code. Teams that want the type safety and performance of WebAssembly without giving up familiar HTML authoring get a clean split between design and logic.
The framework includes examples for common patterns: a counter, live search, keyed lists, and async data fetching. Each one demonstrates the same structure, an HTML template and a Rust module paired by the `template!` macro, so newcomers can read a complete working component in minutes.