← All posts

euv: a Rust and WebAssembly UI framework for the browser

Intro guide to euv: virtual DOM, reactive signals, the html! macro, and mount — declarative frontend with Rust type safety compiled to WASM.

Contents

In brief

euv is a new frontend framework in Rust compiled to WebAssembly. It combines a virtual DOM, reactive signals, and the html! macro with HTML-like syntax. Spiritually close to React and Solid, but built on the Rust ecosystem: types, performance, and compile-time guarantees.

What happened

A getting-started guide on Dev.to covers install via cargo add euv, a minimal “Hello, euv!” app, and core concepts. The root function returns VirtualNode, markup lives in the html! macro, and mounting is mount("#app", app).

Advertised features out of the box:

  • Rust + WASM — typed frontend with near-native browser performance.
  • Virtual DOM — diff/patch instead of hammering the real DOM.
  • Reactive signalsuse_signal, computed!, watch!; only affected nodes update.
  • Components — reusable blocks with typed props.
  • Animations — built-in CSS keyframes (euv-spin, euv-fade-in, etc.).
  • Browser APIs — Window, Document, Storage, Clipboard via the prelude.
  • Asyncspawn_local, Promise and Response helpers.

A counter example shows the pattern: a count signal, an onclick handler with count.get() / count.set(...), automatic re-render of touched UI.

Why it matters

“Rust in the browser” has long promised an alternative to JS frameworks, but the entry cost is often high: different toolchain (wasm-pack, trunk), different error model, fewer ready-made UI libraries. euv bets on familiar declarative UX — macros instead of JSX, signals instead of hooks — lowering the cognitive gap for React/Solid developers.

For teams already on Rust backend-side, it is a chance to unify language across the stack without two type worlds. For experiments, it is a way to see whether WASM UI competes with a typical JS bundle on heavy interactive widgets.

In practice

  1. Set up a WASM projecttrunk or wasm-pack for build and dev server.
  2. Add the dependencycargo add euv.
  3. Define the root — function -> VirtualNode with html! { ... }.
  4. Mountmount("#app", app) or selectors body, .root, main.
  5. Stateuse_signal for local state; computed! for derived values.
  6. Eventsonclick: move |event| { ... } inside macro elements.
Concept JS-world analog
html! JSX / templates
use_signal useState / signals
mount createRoot().render
VirtualNode Virtual DOM tree

Takeaway

euv is another “Rust + WASM on the frontend” candidate, but focused on a familiar declarative model rather than low-level bindings. Worth trying on an isolated widget or internal tool before betting a whole SPA — the WASM toolchain still demands CI discipline and artifact size awareness.