2026/7/3

小工具开发架构:Web 在线版 + Tauri 桌面版

为了同时交付 Web 在线版和 Windows 桌面版,我选择用 Web UI 作为核心,再用 Tauri/Rust 打包桌面壳。

小工具开发架构:Web 在线版 + Tauri 桌面版

02 web tauri architecture

确定要长期做小工具之后,我首先要解决的是技术架构问题。

我的目标很明确:每个工具都要有 Web 在线版,也要有 Windows 桌面版 EXE。Web 版方便用户直接使用,也方便放进个人博客;桌面版方便用户长期离线使用,也能展示完整交付能力。

问题是,如果 Web 写一套,桌面再写一套,后续维护会很痛苦。一个小功能要改两遍,一个 UI 细节要调两遍,测试和发布也要拆成两条线。这对大量小工具来说不是好方案。

我为什么没有选择纯 Rust UI

一开始我也考虑过纯 Rust 桌面 UI。Rust 本身性能强,打包后的程序也可以很可靠。但如果目标是做出接近苹果级别的 UI 质感,纯 Rust UI 的成本会明显变高。

桌面 UI 不只是把按钮和输入框摆出来。它还涉及排版、动效、响应式布局、细腻的 hover 状态、空状态、错误状态、暗色模式、不同窗口尺寸下的稳定表现。Web 前端在这些方面有成熟的生态和更高的表达效率。

所以我的判断是:不要为了“纯”而牺牲效率。对小工具来说,真正重要的是打开快、操作顺、界面舒服、功能稳定。

Web UI 做核心

最终我选择把 Web UI 作为核心。

也就是说,每个工具的主要界面、交互和业务逻辑都用前端技术实现。目前第一版使用的是 Svelte + TypeScript + Vite。这样做有几个好处:

  • 同一套 UI 可以直接构建成 Web 静态页面。
  • 同一套 UI 也可以被 Tauri 打包进桌面版。
  • UI 迭代速度快,适合做精致的小工具界面。
  • 静态页面部署简单,不需要复杂后端。

架构大概是这样:

flowchart LR
  A["一套 Svelte/TypeScript UI"] --> B["Web 静态版"]
  A --> C["Tauri 桌面版"]
  C --> D["Rust 本地能力"]
  B --> E["博客在线使用"]
  C --> F["Windows EXE 下载"]

Tauri/Rust 负责桌面能力

桌面版选择 Tauri,是因为它比 Electron 更轻,更适合小工具。

Electron 的优势是生态成熟,但它通常会带来更大的体积。小工具如果动辄几十上百 MB,会和“轻、快、干净”的目标冲突。Tauri 使用系统 WebView,再用 Rust 做本地能力,整体更符合我的方向。

yuan-image-redactor 里,桌面版目前主要承担窗口和打包能力。后续如果工具需要访问文件系统、系统对话框、原生保存窗口、后台任务或更强的本地处理能力,就可以逐步把这些能力放到 Rust/Tauri 侧。

响应速度怎么保证

“快”不是只靠选框架,而是靠整体约束。

我的基本原则是:

  • 能静态部署的就静态部署。
  • 能本地处理的就本地处理。
  • 控制依赖数量,避免把小工具做成大应用。
  • 首屏只加载必要内容。
  • 交互逻辑尽量直接,不绕复杂状态机。
  • 桌面版隐藏终端窗口,双击打开就像正常软件。

第一版图片打码工具构建后,前端产物很轻,桌面 EXE 也能直接运行。它不是一个复杂产品,但已经证明这个架构可以把 Web 和桌面两条线连接起来。

交付目录

为了让每个工具都能统一发布,我把输出目录固定成:

release/html
release/win

release/html 放 Web 静态版,可以部署到博客或静态托管平台。release/win 放 Windows 桌面版 EXE 和工具使用说明。

这个约定很重要。只要每个工具都遵守同样的目录结构,后续发布、写文章、上传 Release、更新索引都可以标准化。

小结

这套架构不是为了追求技术名词,而是为了服务我的真实目标:大量生产干净、快速、精致、可发布的小工具。

Web UI 给我足够高的界面表达效率,Tauri/Rust 给我桌面交付能力。两者结合后,我可以用一套核心代码同时产出在线版和 EXE,这对长期做工具库非常关键。