Rust 桌面 GUI 框架横评:iced · egui · Dioxus · Tauri 2 · Slint
一句话:五个都能做出生产级桌面应用,但它们回答的是不同的问题——egui 回答「怎么最快画出工具」,iced 回答「怎么用 Elm 心智做纯 Rust 应用」,Dioxus 回答「怎么用 React 心智写全 Rust 跨端」,Tauri 2 回答「怎么把成熟的 Web 前端装进最小的原生壳」,Slint 回答「怎么一份 UI 从桌面下沉到 MCU」。 版本基线(2026-09):iced 0.13.x(0.14 开发中)· egui/eframe 0.36.x · Dioxus 0.7.x · Tauri 2.x(2.0 于 2024-10 稳定)· Slint 1.17.x。 图:6 张内嵌 base64 SVG,无外部依赖。所有性能类说法只给量级并标注来源可靠度,不伪造 benchmark。
目录
一、横评总览:先给结论
一行版结论(细节在后面十二节展开):
| 内部工具 / 调试面板 / 游戏工具,最快出活 | egui | 立即模式零仪式感,一个函数就是一个界面 |
| 纯 Rust 桌面应用,要架构可长期演进 | iced | Elm 单向数据流,状态变更可追溯;COSMIC 桌面验证过体量 |
| 复用 Web 前端团队 / 已有 Web 资产,要移动端 | Tauri 2 | 前端随便选,包体最小,移动端稳定,安全模型完备 |
| 全 Rust 但想要 React 心智,网页/桌面/移动一把梭 | Dioxus | RSX + 信号 + 全栈 server functions + 热补丁 |
| 嵌入式 / 工控 HMI / 类 Qt 工作流 / 要商业支持 | Slint | 唯一能 no_std 下沉到 MCU 的;DSL 设计协作友好 |
五维总表:
| UI 范式 | Elm(保留模式) | 立即模式 | RSX + 信号(React 式) | 由前端框架决定 | 声明式 .slint DSL |
| 渲染 | 自绘:wgpu + tiny-skia | 自绘:wgpu / glow | 桌面=系统 WebView;Blitz 自绘实验 | 系统 WebView | 自绘:Skia / FemtoVG / 软件 |
| UI 语言 | Rust | Rust | Rust(RSX 宏) | HTML/CSS/JS 或 Rust→WASM | .slint + Rust/C++/JS/Python |
| 移动端 | 无官方 | 实验 | 官方支持 | 稳定(iOS/Android) | 预览 |
| Web | 实验 | 一级(WASM) | 一级 | 不适用(自身即壳) | 预览(WASM) |
| 嵌入式/MCU | 否 | 需自行集成 | 否 | 否 | 一级(no_std) |
| 许可 | MIT | MIT/Apache-2.0 | MIT/Apache-2.0 | MIT/Apache-2.0 | GPLv3 / 免版税 / 商业 三选一 |
| 代表 | System76 COSMIC 桌面 | rerun、海量 Rust 工具 | 自家全栈应用生态 | 大量商业跨端应用 | 工业 HMI、车机、白电 |
二、五框架画像
iced:Elm 的 Rust 化身
- 定位:受 Elm 启发的纯 Rust GUI 库——状态 + Message + update + view 四件套,界面是状态的纯函数。
- 亮点:架构最「正」,大型应用不易腐化;wgpu 渲染 + tiny-skia 软件兜底;被 System76 选为 COSMIC 桌面环境(整个 Linux 桌面!)的 UI 框架,体量已被验证。
- 短板:官方自称 experimental,API 每个 0.x 版本都可能大改;文档长期只有 book + 示例;无官方移动端;无障碍支持不完整。
- 气质:给「愿意读源码、想把应用写成一门架构」的 Rust 原教旨主义者。
egui:立即模式的效率怪物
- 定位:立即模式 GUI——每帧重跑一遍 UI 代码,界面就是代码此刻的输出;eframe 提供开箱窗口壳。
- 亮点:心智负担全场最低(无回调无绑定无 diff);渲染器无关(输出三角网格,wgpu/glow/自定义皆可),因此能嵌进任何游戏引擎/wgpu 应用;Web(WASM) 是一级公民;AccessKit 无障碍默认启用(Windows/macOS);0.36 起要求 Rust edition 2024。
- 短板:默认观感是「调试 UI」风(可主题化但要花功夫);复杂自适应布局(flexbox/grid 级)能力弱;文本排版对复杂文种支持有限。
- 气质:工具人之选——十分钟出一个能用的面板,是它的主场。
Dioxus:React 心智,Rust 身体
- 定位:组件 + RSX(≈JSX)+ 细粒度信号;一份代码目标 Web/桌面/移动/全栈。
- 亮点:0.7 的 Subsecond 热补丁能热替换 Rust 代码(不只前端资源);use_signal 细粒度更新;全栈 server functions(Axum 底座);桌面/移动官方支持;风投支持(YC),迭代极快。
- 短板:桌面渲染现状 = 系统 WebView(wry/tao,与 Tauri 同底座),自研 Blitz/Dioxus Native(WGPU 直渲 HTML/CSS,Taffy 布局)仍是实验品;框架年轻,版本间破坏性变更常见。
- 气质:给「前端背景、想 all-in Rust、能接受追新」的团队。
Tauri 2:最小的壳,最大的自由
- 定位:不是 GUI 工具包,是应用外壳——UI 交给系统 WebView 里的任意 Web 前端,逻辑放 Rust 进程,中间是 IPC。
- 亮点:包体最小(不带浏览器引擎,安装包常见个位数 MB);2.0 起 iOS/Android 稳定;IPC v2 支持二进制 Raw Payload 与 Channel;capabilities/permissions 安全模型 + CSP;插件生态最丰富。
- 短板:三平台 WebView 内核不同(WebView2/WKWebView/WebKitGTK),渲染细节与可用 Web API 有差异,Linux 的 WebKitGTK 是常见坑位;性能上限受 WebView 与 JS 桥制约。
- 气质:Electron 的正统继承人,减去 150MB 的 Chromium。
Slint:从桌面下沉到单片机
- 定位:声明式 .slint DSL 编译为原生代码;创始团队出自 Qt/QML,目标就是「现代 Qt」。
- 亮点:唯一能 no_std 跑上 MCU 的(数百 KB RAM 级设备可用软件渲染器);Skia/FemtoVG/软件三渲染器;Rust/C++/JS/Python 四语言绑定;live-preview 即改即见;有商业公司背书与付费支持。
- 短板:要学一门 DSL;许可三选一有决策成本(嵌入式发货要么 GPL 要么付费);社区规模小于其余四者。
- 气质:给「有设计师协作、有嵌入式野心、想要 Qt 式工作流」的团队。
三、渲染路线对比:WebView vs 自绘
三条路线的本质取舍:
| 排版/字体/IME | 系统浏览器引擎全包,最省心 | 框架自己实现,能力参差 | 同左 |
| 跨平台一致性 | 三平台内核不同,有差异 | 像素级一致 | 像素级一致 |
| 包体 | 极小(引擎在系统里) | 中(带渲染栈与字体处理) | 中 |
| 性能上限 | 受 WebView + JS 桥制约 | 直控 GPU,上限最高 | CPU 光栅化,够用但别做重动画 |
| 无 GPU 环境 | WebView 自己会退化 | 需软件后端兜底 | 天生为此而生 |
| CSS 生态复用 | ✔ 全量复用 | ✘(Blitz 实验性支持 HTML/CSS) | ✘ |
一个常被忽略的事实:Dioxus 桌面今天与 Tauri 用的是同一个 WebView 底座(wry/tao)。两者的差异不在渲染,而在「UI 用什么语言写」(Rust RSX vs 任意 Web 前端)。Dioxus 押注的未来是 Blitz——用 WGPU 直渲 HTML/CSS(Taffy 布局引擎),成了它就同时拥有 Web 生态与自绘一致性,但今天它还是实验品。
四、编程范式对比:同一个计数器的五种写法
同一个「计数器」,五种世界观。依赖基线:
# 各框架最小依赖(五选一)
iced = "0.13"
eframe = "0.36" # egui 应用壳
dioxus = { version = "0.7", features = ["desktop"] }
tauri = "2" # 另需 build 依赖 tauri-build
slint = "1.17" # 另需 build 依赖 slint-build
iced —— Elm 四件套(0.13 的极简入口):
use iced::widget::{button, column, text};
use iced::Element;
#[derive(Default)]
struct Counter { value: i64 }
#[derive(Debug, Clone, Copy)]
enum Message { Inc, Dec }
fn update(c: &mut Counter, m: Message) {
match m { Message::Inc => c.value += 1, Message::Dec => c.value -= 1 }
}
fn view(c: &Counter) -> Element<'_, Message> {
column![
button("+").on_press(Message::Inc),
text(c.value).size(40),
button("-").on_press(Message::Dec),
].into()
}
fn main() -> iced::Result {
iced::run("Counter", update, view) // 状态默认 Default::default()
}
egui —— 立即模式(界面 = 每帧代码的输出):
struct App { value: i64 }
impl eframe::App for App {
fn update(&mut self, ctx: &egui::Context, _f: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Counter");
ui.horizontal(|ui| {
if ui.button("−").clicked() { self.value -= 1; } // 无回调:当帧判断
ui.label(self.value.to_string());
if ui.button("+").clicked() { self.value += 1; }
});
});
}
}
fn main() -> eframe::Result {
eframe::run_native("Counter", Default::default(),
Box::new(|_cc| Ok(Box::new(App { value: 0 }))))
}
Dioxus —— RSX + 信号(写法≈React,类型是 Rust):
use dioxus::prelude::*;
fn main() { dioxus::launch(app); }
fn app() -> Element {
let mut count = use_signal(|| 0);
rsx! {
h1 { "计数: {count}" }
button { onclick: move |_| count += 1, "+1" }
button { onclick: move |_| count -= 1, "-1" }
}
}
Slint —— DSL 声明 + Rust 驱动(UI 与逻辑物理分离):
// ui/counter.slint
import { Button, VerticalBox } from "std-widgets.slint";
export component Counter inherits Window {
in-out property <int> value: 0;
VerticalBox {
Text { text: "计数: " + root.value; font-size: 24px; }
Button { text: "+1"; clicked => { root.value += 1; } }
Button { text: "-1"; clicked => { root.value -= 1; } }
}
}
slint::include_modules!(); // build.rs 里 slint_build::compile("ui/counter.slint")
fn main() -> Result<(), slint::PlatformError> {
let ui = Counter::new()?;
ui.run()
}
Tauri 2 —— command + 前端(UI 在 Web 侧,Rust 只暴露能力):
#[tauri::command]
fn add(current: i64, delta: i64) -> i64 { current + delta }
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![add])
.run(tauri::generate_context!())
.expect("run tauri app");
}
// 前端任意框架里(计数状态本身就放前端)
import { invoke } from '@tauri-apps/api/core';
const next = await invoke('add', { current: 0, delta: 1 });
五段代码放在一起,差异一目了然:iced 把状态流放在台面上;egui 把帧放在台面上;Dioxus 把组件放在台面上;Slint 把界面描述放在台面上;Tauri 把进程边界放在台面上。
五、Tauri 2 单独拆解:它和其余四个不是一类东西
把 Tauri 2 和另外四个放一张表里横比,容易得出错误结论——它其实是另一层的东西:
- 它不画 UI:渲染整个托付给系统 WebView;你甚至可以把 Dioxus / Leptos / Yew 当 Tauri 的前端,二者是组合关系不是竞争关系。
- IPC v2 是 2.0 的核心升级:invoke 命令 + 事件 + Channel(Rust→前端流式推送);Raw Payload 允许二进制直传,绕开 JSON 序列化——大文件/图像场景不再卡桥。
- 安全模型是它对 Electron 的代差:每个窗口按 capabilities 显式声明能用哪些 permissions(文件系统、shell、通知…),默认拒绝,外加 CSP 注入;插件也纳入同一权限体系。
- 移动端在 2.0 转正:iOS/Android 与桌面共用一套项目结构(cargo-mobile2 底座),tauri ios/android dev 直接起模拟器。
- 代价也要写清楚:WebKitGTK(Linux)与另两家内核行为差异是最大槽点来源;前端↔Rust 每次过桥都有序列化/调度成本,高频小消息要合批。
六、跨平台能力矩阵
几条矩阵之外的注脚:
- iced 的 Web 后端长期处于实验/半维护状态,别按一级能力规划。
- egui 的移动端能跑(eframe 有 Android 支持路径)但属于「自己动手」级;它的 Web(WASM) 反而是最成熟的自绘方案之一。
- Dioxus 移动端是官方叙事的一部分(一份代码五端),但生态年轻,深度依赖原生能力时要有写平台胶水的准备。
- Slint 的嵌入式是真·一级:官方演示能在 ESP32 / STM32 级 MCU(数百 KB RAM + 软件渲染)上跑完整 UI,这是其余四家完全没有的维度。
- 桌面三平台五家都稳,差别在细节:自绘系(iced/egui/Slint)三平台像素一致;WebView 系(Tauri/Dioxus)要为 Safari 系/WebKitGTK 留兼容性测试预算。
七、性能与资源占用:只谈量级,诚实标注
性能横评是重灾区——网上流传的对比多数拿「hello world 包体」说事。这里只给量级与机制解释,并标注可靠度:
| 安装包体 | 个位数 MB 常见(引擎在系统里) | 约 5–20MB(带渲染栈;strip + release 后) | 官方口径 + 社区实测量级 |
| 内存 | 页面内存 + WebView 共享库;显著低于 Electron(官方称比 Electron 省一半以上很常见) | 通常更低(无 JS 引擎/DOM) | ⚠️ 因应用差异巨大,只可比量级 |
| 冷启动 | WebView 初始化有可感知成本(Windows 上 WebView2 首启尤甚) | 基本即开即用 | 社区共识,无权威对拍 |
| 运行帧率上限 | 受 DOM/JS 制约,重可视化需 canvas/WebGL | 直控 GPU,60/120fps 可控;egui 默认按需重绘并不烧 CPU | 机制推导 |
| 对照背景板 | Electron 安装包常见 80–150MB、内存以数百 MB 起步 | — | 公开常识量级 |
⚠️ 三个诚实声明:其一,没有任何一家发布过五框架同条件对拍,本文不编造数字;其二,「Tauri 包小」的前提是系统有 WebView(Windows 老系统需分发 WebView2 Runtime,约 100MB+ 的在线/离线引导,装完全局共享);其三,立即模式≠费电,egui 在无交互时不重绘。
八、中文 IME、可访问性与文本渲染
对中文团队,这一节可能比性能更该看:
| 中文 IME | winit 系历史痛点,近年改进但仍有候选框定位等毛边 | 同 winit 系,桌面基本可用 | WebView 提供,省心 | WebView 提供,省心 | 支持,成熟度视后端 |
| CJK 字体 | 需自带/指定字体,注意包体 | 需自带字体(默认字体不含 CJK) | 系统字体栈全套 | 系统字体栈全套 | 需配置字体,嵌入式场景可裁剪字库 |
| 复杂排版(换行/竖排/RTL) | 有限 | 有限(复杂文种是已知短板) | 浏览器级,最强 | 浏览器级,最强 | 中等 |
| 无障碍 | AccessKit 集成未完成(长期 issue) | AccessKit 默认启用(Win/mac;Web 端无) | WebView=ARIA;Blitz 部分 | 浏览器级 ARIA,最完整 | 桌面后端接入 AccessKit,组件带 accessible 属性 |
结论很直白:输入法和排版要「零操心」,选 WebView 路线;自绘路线里 egui/Slint 的无障碍已可用,iced 这块最弱。做政企/无障碍合规项目,这一行可能直接否掉候选。
九、许可证与商业模式
| iced | MIT | 随便用 |
| egui | MIT OR Apache-2.0 | 随便用 |
| Dioxus | MIT OR Apache-2.0 | 随便用(公司靠云服务/部署赚钱) |
| Tauri 2 | MIT OR Apache-2.0 | 随便用(基金会治理 + CrabNebula 商业服务) |
| Slint | GPLv3 / Royalty-Free / 商业 三选一 | 见下 |
Slint 的三选一要单独讲清楚:
决策提示:企业内部工具五家全部免费无忧;只有「闭源 + 嵌入式发货」这个组合会碰到 Slint 的收费闸门。
十、开发体验:热重载、工具链与学习曲线
| 热重载 | 无官方 | 不太需要(编译快 + 立即模式) | Subsecond 热补丁:连 Rust 逻辑都能热换 | 前端 Vite HMR 秒级;Rust 侧需重编 | live-preview:.slint 即改即见 |
| 脚手架 | 无(看 examples) | 无需 | dx new / dx serve | create-tauri-app + tauri dev 一条龙 | VSCode 扩展 + SlintPad 在线玩 |
| 调试 | Rust 调试器 | 自带 inspector(ctx.debug…) | 浏览器 DevTools + Rust | 浏览器 DevTools 全套 + Rust | 预览器 + Rust/C++ 调试器 |
| 学习曲线 | 中高(Elm 心智 + API 变动) | 最低 | 低(前端背景)/中(纯后端背景) | 低(会 Web 就会)+ Rust 命令层 | 中(学 DSL,但 DSL 本身简单) |
| 文档 | 偏薄(book + 示例) | 好(docs.rs + demo 站) | 好且新 | 最全(官网指南成体系) | 好(官方教程 + 参考完整) |
DX 的分水岭在「改一行 UI 要等多久」:Dioxus(热补丁)、Slint(预览器)、Tauri(HMR)是秒级;egui 靠编译快 + 心智简单硬拉平;iced 改一行等一次全量编译,大项目里最疼。
十一、生态与成熟度
| Tauri 2 | ≈ 9 万+,五者最高 | Tauri 基金会(Commons Conservancy)+ CrabNebula | 大量商业桌面应用;生态插件最多 |
| Dioxus | ≈ 3 万 | Dioxus Labs(YC 融资) | 自家全栈生态,增速最快 |
| iced | ≈ 2.5–3 万 | 社区 + System76 深度投入 | COSMIC 桌面环境整套 UI |
| egui | ≈ 2.5–3 万 | emilk 主导 + rerun 公司反哺 | rerun 可视化、无数内部工具、游戏引擎标配调试 UI |
| Slint | ≈ 2 万 | SixtyFPS GmbH(商业公司) | 工业 HMI / 车机 / 白电等嵌入式出货 |
成熟度的另一面是稳定性承诺:Tauri 2 与 Slint 1.x 有明确的语义化版本纪律;egui 每年数个 0.x 版但迁移说明详尽;Dioxus 迭代最快、破坏性变更也最多;iced 官方直言 experimental,0.x 之间 API 会大改——把「升级成本」计入选型,而不只看今天好不好用。
十二、选型决策树与场景建议
按场景落到人:
- 运维面板 / 抓包器 / 性能分析器 / 游戏编辑器:egui。立即模式对「数据每帧都在变」的界面是降维打击。
- 面向最终用户的桌面产品,团队有前端:Tauri 2。UI 质感天花板最高(就是 Web 的天花板),设计资源全能复用。
- 同上,但团队想只写 Rust:Dioxus(接受追新)或 iced(接受手工与编译等待,换架构稳)。
- 嵌入式 HMI / 车机 / 仪器面板,顺带出个桌面版:Slint,没有第二个答案。
- 组合拳也常见:egui 嵌进 wgpu/游戏引擎当调试层;Dioxus 作为 Tauri 的前端(全 Rust + Tauri 的插件/打包/安全);Slint 桌面版验证 UI、同一份 .slint 下沉到设备。
十三、与 CMX 工作区的落地呼应
对照本工作区(元数据驱动企业平台,前端已有成体系的 Web 资产):
一句话收束
五个框架其实是五个问题的答案:egui 答「多快」,iced 答「多正」,Dioxus 答「多全」,Tauri 答「多轻」,Slint 答「多深」。 先想清楚你的问题是哪一个,答案自然浮出来——而对一个已有 Web 资产的团队,Tauri 2 往往是把存量变现的最短路径。
参考:iced.rs 与 book.iced.rs、github.com/emilk/egui 与 egui.rs、dioxuslabs.com(0.7 发布说明 / Blitz / Subsecond)、v2.tauri.app(IPC / capabilities / mobile 指南)、slint.dev(licensing / embedded / 渲染器文档)、System76 COSMIC 公告。版本以 2026-09 各官方文档为准;star 数与体积/内存均为量级说法,选型前请以当期实测为准。

