Notes on the Rust UI Ecosystem
"You take the blue pill... the story ends, you wake up in your bed and believe whatever you want to believe. You take the red pill... you stay in Wonderland, and I show you how deep the rabbit hole goes."
— Morpheus, The Matrix
That choice feels a lot like the one you make when you decide to build a UI in Rust. You're deliberately stepping away from the well-trodden path of JavaScript frameworks into an ecosystem that promises more performance, more control, and a different way of thinking. But taking the red pill is just the first step. The rabbit hole of the Rust UI ecosystem is deep, with its own set of paths and trade-offs.
This post is my map of that Wonderland. We'll start by exploring the two fundamental ways Rust frameworks handle UI updates—the Virtual DOM and fine-grained reactivity. Then we'll look at the different approaches for desktop apps before surveying the major players in the ecosystem. My goal is to lay out the core trade-offs to help you navigate it.
The Core Architectural Divide: State and Rendering
From what I can tell, the first major split comes down to how a framework handles state changes and updates the UI. This is most relevant for web-based frameworks (WASM), but the concepts echo in the native space as well. Here’s a simplified flowchart comparing the two update models:
Figure 1: A comparison of the update process for Virtual DOM vs. fine-grained reactivity.
1. The Virtual DOM (VDOM)
This is the model popularized by React and is the more established pattern in web development. When application state changes, the framework builds a new representation of the UI tree in memory (the "virtual" DOM). It then diffs this new tree against the previous one to compute a minimal set of changes, which are then applied to the actual browser DOM.
Frameworks: Yew, Dioxus
Trade-offs: This approach is mature and well-understood. For anyone with a background in React, the component model is immediately familiar. The cost is the overhead of the diffing process itself. It consumes CPU and memory to build and compare trees, which can be less performant than more direct methods.
2. Fine-Grained Reactivity
This is a more recent model that aims to eliminate the VDOM overhead entirely. Instead of rerendering entire components, state is wrapped in reactive primitives (often called signals). These primitives form a dependency graph. When a signal is updated, it directly notifies the specific parts of the UI that depend on it.
Frameworks: Leptos, Sycamore
Trade-offs: This is almost always faster and results in smaller code bundles. The work done is proportional to the size of the data change, not the size of the component tree. The mental model is different from React's, focusing on data flow through signals, which can present a learning curve. The ecosystem around this pattern, while maturing quickly, is also newer than the VDOM's.
The Desktop Approach: How to Draw Pixels
When building a native desktop application, the primary decision is what will actually be responsible for rendering the UI. This can be visualized as three distinct architectural layers:
Figure 2: A high-level view of the three main desktop rendering architectures.
1. The WebView Model
Here, the framework embeds the operating system's native web browser engine into a standard window. The UI itself is built with web technologies, while a privileged Rust backend handles native operations.
Framework: Tauri is the clear leader in this space.
Trade-offs: This allows leveraging the entire web ecosystem for UI development. Tauri improves significantly on the Electron model by using the OS's existing webview, resulting in smaller and more secure applications. However, performance and memory usage are still tied to the browser engine.
2. The Native Rendering Model
These frameworks bypass the web stack completely and use the system's graphics libraries to draw every pixel of the UI directly.
Frameworks: Slint, Iced, and the experimental Xilem.
Trade-offs: This provides the best possible performance and the lowest resource usage. The downside is that you are constrained to the components and styling capabilities provided by the framework itself, which is less flexible than CSS.
3. The Custom Renderer Model
A framework can provide its own GPU-accelerated rendering engine that works consistently across platforms, drawing to either a native window or a web canvas.
Framework: Makepad is the primary example here.
Trade-offs: This gives you pixel-perfect consistency everywhere and opens the door for highly visual applications. Makepad's live-editing environment is a major feature. It's a more integrated but also more opinionated platform.
A Brief Survey of the Frameworks
Based on those architectural models, here's my current take on the major frameworks.
Leptos
A modern, fine-grained reactive framework for web apps. Its "server functions" concept and isomorphic approach make it powerful for building fast-loading, full-stack applications. Probably my starting point for a new web project.
Tauri
A tool for building desktop apps with a web frontend. Not a UI framework itself, but a way to package any web application into a small, secure native binary. The logical successor to Electron for many use cases.
Dioxus
A VDOM-based framework with a strong emphasis on portability ("write once, run anywhere"). Its renderer-agnostic design makes it a good choice if the primary goal is to target as many platforms as possible from a single codebase.
Yew
One of the oldest and most mature VDOM frameworks, heavily inspired by React. A safe, familiar choice for a team coming from a heavy React background.
Slint
A native-rendering framework focused on professional and embedded use cases. It leverages this model to create performant UIs with a tiny memory footprint. Has its own declarative markup language and offers C++, JS, and Rust APIs.
Iced
A native-rendering framework inspired by the Elm architecture. Its message-passing model, where every interaction creates a message that immutably updates state, makes application logic very predictable and easy to debug.
Xilem
An experimental native framework exploring a purely reactive, data-first approach to native UI. A project to watch for its potential influence on the future of Rust GUIs.
Makepad
A complete platform with its own custom renderer and a live-editing IDE. Uses its unique architecture to create visually rich applications that are pixel-perfect on both web and desktop. Interesting for applications that require custom, non-standard UI elements and a design-focused workflow.
There are others, like egui for immediate-mode GUIs, which is excellent for debug overlays or in-game tools.
Where I've Landed
After surveying the landscape, my main takeaway is that there is no single "best" tool, only the right tool for a specific set of trade-offs. The ecosystem is healthy precisely because different projects are exploring different points in the design space. The decision process can be roughly mapped out like this:
Figure 3: A simplified decision tree for choosing a Rust UI framework.
Taking the red pill means embracing those trade-offs. With a clearer map of the terrain, you can pick the path that fits your project—and know exactly what you're getting in return.
- Lex
Join the discussion
Comments are powered by Giscus, which uses GitHub Discussions behind the scenes.
You will need a GitHub account to leave a comment.