AI 时代,我为什么推荐用 cj-tauri 开发桌面应用
先说一件更基础的事:我们写代码的方式变了。
两年前写一个桌面工具,节奏是「我敲、我调、我试」。现在是「我描述、AI 落笔、编译器裁决」——我给出意图,AI 给出几百行,然后真正的裁判不是 AI 的自我总结,而是编译器那句 error:。
这个转变把三个原本次要的成本顶到了台前:编译要等多久、构建目录吐多少垃圾、产物交付给别人有多大。以前一天编十次,慢一点无所谓;现在 AI 一轮改完就想立刻跑起来看,编译慢就从「可以忍」变成「打断工作流」。以前 target/ 涨到几个 G 反正只有我自己看;现在要给同事、给用户、给一台干净的机器甩一个能双击就跑的文件。
cj-tauri 就是我在这个背景下用来写桌面应用的东西。它不是玩具:30 多个可运行的示例、101 个仓颉源文件两万五千多行、351 个单元测试、Windows/Linux/鸿蒙三端有真机取证。下面把我选择它的理由、以及它的真实代价,一条条摊开讲,数字都给来源,方便你复核。

一、先说清 cj-tauri 是什么
一句话:它是「仓颉版 Tauri」——后端用仓颉静态编译成原生二进制,前端是你熟悉的 Web 技术,界面跑在系统 WebView 里。
这个定位决定了它的形状:
- 不带 Chromium、不带 Node。界面用系统自带的 WebView(Windows 是 WebView2、Linux 是 WebKitGTK、鸿蒙是 ArkWeb),你的产物里没有第二个浏览器内核。
- 前端随便用什么。
create缺省给一个零 Node 的内联 HTML 模板,也支持 Vue 3 / React 18 模板走 Vite。 - 命令面照着 Tauri 抄。
npx cj-tauri create建工程,cj-tauri dev起开发服务器,cj-tauri build出产物。从 Tauri 过来的人几乎不用重学脚手架。 - 一份后端代码多端跑。平台差异只允许出现在两处:仓颉侧
@When条件编译,和 C 桥native/platforms/*/。

它想解决的问题很朴素:桌面应用最贵的那部分从来不是业务代码,而是「把业务代码变成用户能双击的东西」这一路的基础设施。这条路 Tauri 用 Rust 走通过一次,cj-tauri 想用仓颉再走一次——而且是能同时走到鸿蒙的那一次。
二、第一个理由:产物是真的小,而且「小」能复核
「小」这个字在宣传语里不值钱,值钱的是它能被一条条复核。
我刚在本机重新量了一遍(2026-11-08):
| 产物(Windows 单文件 exe) | 体积 |
|---|---|
serial-waveform.exe | 4.89 MB |
markdown-notes.exe | 5.20 MB |
cj-link.exe | 5.90 MB |
modbus-poll.exe | 5.97 MB |
typing-poem.exe | 6.02 MB |
movie.exe | 10.04 MB |
music.exe | 10.21 MB |
leetcode-gui.exe | 10.43 MB |
轻量工具落在 4.7~6MB,带 HTTPS 和较多资源的示例在 10MB 上下。
这里我要主动补一句反例,避免你按「都很小」预期:同一批产物里还有两个重度示例——内嵌了 AI agent 的 ai-chat.exe 是 26.75MB,内嵌完整编辑器的 cjnote.exe 是 34.35MB。它们大是因为真的带了东西(页面资源、内嵌二进制),不是因为框架本身肥。框架加一个空窗口的基线,就是上表那 4~6MB 的量级。

体积只是表象,真正决定「能不能甩给别人」的是依赖表。仓库里有实测记录(2026-10-13,八份产物逐个 objdump 核过):
- 八份产物导入的 DLL 名字加起来只有 9 个,全是 Windows 系统自带的:
KERNEL32/USER32/SHELL32/ole32/msvcrt/WS2_32/comdlg32/dbghelp,走 HTTPS 的再多一个CRYPT32(读系统证书库)。 - 第三方运行时 DLL 一个都没有:
msvcp*/vcruntime*/libgcc*/libwinpthread*全为零,也没有任何 Node 相关的东西。 - 子系统是
Windows GUI——双击不会先弹一个黑窗口。
这三条合起来才是「免安装」的完整含义:在一台从没装过仓颉 SDK、也没装过 VC++ 运行库的 Windows 上,双击就能开窗。仓颉运行时的 TLS 加载器那类按名字动态加载的 DLL 是边界情况,仓库里如实写了「未验证前不下结论」,我也不在这里替它吹。
对 AI 协作来说,这件事的意义比「省硬盘」更实在:你交付出去的是一份可审计的产物,而不是一棵几百个包的依赖树。出问题时排查范围是你自己写的两万行,不是三十万行第三方代码。
三、第二个理由:编译等待,短到不会打断 AI 节奏
这是我认为在 AI 时代最被低估的一条。仓库里的实测表(同一台机器、同一份脚本):
| 项目 | 实测 |
|---|---|
最小示例 examples/hello 全量冷编译(静态链入框架) | 50 秒 |
| 同一示例改一行再编(增量) | 25 秒 |
构建目录 target/(该示例 / 框架本身) | 6.7M / 42M |
产物 main(静态链接) | 4.5M |
| 独立小程序(leetcode 判题器,静态链接 + strip) | 冷编译 0.4~1 秒,产物 2.7M |
翻译成日常感受:全量几十秒,增量二十几秒,写小工具的编译快到感觉不到(0.4 秒那种,基本等于「按下按钮就出结果」)。构建垃圾是几十兆级,不是几个 G 级——我现在的框架 target/ 目录就是实打实的 42M。
这直接改变了 AI 协作的闭环速度。AI 一次改动之后,我要的是立刻看到它能不能跑,而不是去泡杯咖啡回来发现编译报错在第一行。反馈周期从分钟级压到秒级,AI 那种「一次改一大片」的用法才真正成立——改错的面大没关系,只要代价低到可以立刻重来。
不过因果要说清楚,这条最容易被误读:
仓颉这边快,一部分是因为项目本身瘦(依赖少、代码短,没有一排第三方 crate 要先编一遍),加上工具链轻。 不是编译器比 rustc 更聪明。Rust 的慢换来的是极致优化和一个巨大到不用自己造轮子的生态。
这笔账怎么算,取决于你在写什么——我不想用它去踩 Rust,只想说清楚「轻量工具、快速迭代」这个场景里,等待时间的差距是真实收益。
四、那 Rust / Tauri 呢:它的代价也是具体的
既然要讲清楚为什么推荐,就得讲清楚我在拿什么做对照。
Rust 是「编译期安全」这条路上最有说服力的答案,Rust + Tauri 也是当下桌面混合开发最成熟的组合。我不否认这些。我想说的只是:它被吐槽最多的两条,恰好是日常最磨人的成本——编译慢、构建目录吐垃圾。
- 依赖一多,泛型单态化 + 过程宏展开一起来,
target/动辄几百 MB 到几 GB(debug 和 release 还各留一份); - 改一行等半分钟是常态,项目大一点、机器差一点,一分钟往上很常见;
- 生态太大也有代价:一个不起眼的工具链,
Cargo.lock里能拽进来上百个包,供应链审计、版本冲突、交叉编译踩坑都从这里来。
这里我必须把方法论摆出来:我这台机器上没装 cargo,所以不做同机、同项目的对照实验,上面这些是业界公认的现象,不是一个我亲手跑出来的数字。而仓颉侧的数字(50 秒 / 25 秒 / 42M)是仓库里脚本可复算的。
拿「我这边的实测」对「对面公认的口碑」是不严谨的对照,所以我把它写成这样:你可以按自己的项目比例去感受,而不是假装我有两组同口径数据。这条线我觉得比多一个漂亮数字重要——毕竟选型错了,是你后面一两年陪着它。
五、第三个理由:AI 写代码时,编译器是最好的审稿人
这一段是我认为 cj-tauri 在「AI 时代」这个题目下最硬的理由,而且它和框不框架无关,是语言层面的。
① 静态类型 + 编译期检查 = 给 AI 的幻觉设了一个落点。
动态语言里 AI 编出来的 API 名字错了,要真跑到那一行才炸;静态编译的语言是编译期就过不去。仓颉属于后者。这套工作流的价值在项目变大时才显出来:本仓 101 个仓颉源文件、25,431 行代码、351 个 @Test——编译器的报错比 AI 的自述可信。它说「改好了」,编译器说「第 340 行类型不匹配」,后者是唯一可以据以行动的信号。
② 语法简单,代码短,AI 一次能改对的面就大。
类型推断、模式匹配、lambda、字符串插值都有,一个命令处理器六行、一个能跑的窗口应用十来行。同一件事用的代码越少,AI 一次改对的概率越高,人 review 的面也越小。FFI 也不隆重——一行 foreign func 直接调系统库,中间没有多余的包装层(本仓的 SQLite 插件就是直接调系统 libsqlite3)。
③ @When 条件编译让「一份代码多端」对 AI 也友好。
不用为每个平台记一套 API:AI 只要在同一个函数里按平台门禁写分支,剩下交给编译器。这比让 AI 记住「Windows 上要这样、鸿蒙上要那样」的三套代码可靠得多。
④ 它多给了一样 Rust 给不了的东西:鸿蒙。
后端逻辑与鸿蒙原生同源,桌面和鸿蒙共用一套业务代码。这在别家语言上没有现成路径。如果你的目标里有鸿蒙 PC,这条几乎是一票否决级别的差异。
六、生态已经不是「一个玩具示例」了
这是我觉得最需要摆事实的一条,因为「新框架」三个字天然让人怀疑能不能用。
我数了下仓库现在有 32 个示例与模板目录,其中大部分是真能跑的工具,不是 hello world:
| 示例 | 一句话 |
|---|---|
modbus-poll | Modbus TCP/RTU 调试工具:多面板并行监控、FC 01-04/05/06/15/16、报文监视、CSV 记录 |
mqtt-client | MQTT 调试台:协议由插件纯仓颉实现(没用现成库),自带 mock broker,E2E 27 条断言 |
redis-client | Redis 调试台:SCAN 游标分页 + MATCH + TYPE 过滤、发布订阅,RESP2 双 socket 自研,47 条断言 |
sqlite-browser | SQLite 浏览器:仓颉 FFI 直连系统 libsqlite3,不经 C 桥 |
http-client | HTTP API 客户端:页面零 fetch,请求全由仓颉侧直发,TLS 走系统证书库、不关校验,55 条断言 |
cj-link | 串口/网络二合一调试助手:串口 + TCP + UDP 共用收发日志,HEX/ASCII、CRC、定时发送 |
cjnote | Markdown 笔记 + 大纲 + 菜单,真实日用级应用 |


配套的还有一套插件体系(fs / shell / serial / dialog / async 等,命令自动登记成 插件名:短名)、三套脚手架模板,以及一份和 Tauri 的逐条概念映射表——#[tauri::command] 对应什么、Capabilities 对应什么、fs:scope 对应什么,迁移时照着改就行。
七、它现在的代价,我也照实说
一个只讲优点的推荐没有价值。以下是我在用、或者明确已知的短板:
① 库生态远小于 crates.io。 很多轮子得自己造——本仓的 MQTT、Redis RESP2 都是纯仓颉手写的。好处是零第三方依赖、可审计;代价是你得自己写。如果你要的是「现成的海量第三方库」,先去 Rust,这句话我是认真的。
② 工具链还在快速演进。 版本配对的坑真实存在(cjc 与 opt 差一代会崩、cjpm 的增量缓存偶尔会跳过链接),所以本仓的验收判定统一成「看产物」而不是「看 build success」。这不是洁癖,是被坑出来的纪律。
③ 平台覆盖有缺口。 Windows / Linux / 鸿蒙(真机闭环)可用,macOS 未做。移动端也没有。
④ 能力矩阵不是满的。 托盘、全局快捷键、文件拖入、原生对话框、系统通知在 Windows/Linux 落地(部分为桩),鸿蒙侧多数能力位为 0 但会如实拒绝而不是假装成功;自动更新(updater)暂无对应物;shell 子进程是同步阻塞、没有流式输出,长驻进程不适用。
⑤ 鸿蒙侧有形状差异。 菜单只支持扁平、无禁用位,嵌套树写法要退化;串口这类能力受系统签名与权限门槛限制。
⑥ Tauri 的习惯要改。 命令三处联动缺一不可(实现 + 注册 + 清单放行),少一处报 command not registered / command not allowed;权限集和 scope 都是「声明 ≠ 放行」,比 Tauri 的 ACL 更显式,也更容易漏。排查第一件事是看桥日志。
八、所以,什么时候该选它
把上面的东西压缩成一张判断表:
| 你的情况 | 建议 |
|---|---|
| 写内部工具、调试台、小桌面应用,要快速迭代 | 很合适。编译秒级,产物 5MB,甩一个 exe 就交付 |
| 用 AI 辅助开发,希望编译期就能拦住错误 | 很合适。静态类型 + 351 个测试,编译器当审稿人 |
| 目标平台包含鸿蒙 PC | 优先考虑。桌面与鸿蒙同源,这是它独有的路径 |
| 交付形态是「给非开发者的免安装单文件」 | 合适。零第三方 DLL、GUI 子系统、双击即开 |
| 重度依赖第三方生态(拿现成 crate 拼装) | 先去 Rust/Tauri。仓颉生态还小,自己造轮子的成本要算进去 |
| 必须支持 macOS / iOS / Android | 暂不适用。这几个平台尚未落地 |
一句话总结:如果你要的是「AI 帮你写 + 编译器把关 + 一条命令出小产物」这套工作流,cj-tauri 很合适;如果你要的是现成的海量第三方库,先去 Rust。 Rust 证明的方向是对的,仓颉是同一方向上的另一个答案。
九、想试试的话,从这三步开始
# 1. 建工程(CLI 是 npm 包,这一步需要 Node)
npx cj-tauri create my-app
# 2. 开发:起 dev server 并开窗(Vite 由 CLI 托管)
cd my-app && cj-tauri dev
# 3. 出产物
cj-tauri build
一个能跑的最小窗口应用大概十来行仓颉——前端是普通 HTML,后端注册一个命令处理器,桥接由框架管好。上手门槛基本等于「会写网页 + 会写一个函数」。
如果你从 Tauri 过来,直接看仓库里的《与 Tauri 的差异清单》:概念映射、行为差异、平台能力差异、迁移清单四节,照着改,一两个小时能把一个小项目挪过来。
结语
我不觉得 cj-tauri 现在就该取代谁。它还很年轻,生态、平台覆盖、工具链成熟度都有明显缺口,我在上面也一条条写了。
但它代表的那个方向我觉得是对的:在 AI 参与写代码之后,桌面开发的竞争点从「功能能不能实现」前移到了「改一次要等多久、交付出去多大、出错时谁替你兜住」。前两件事是工程成本,第三件事是正确性——而静态编译的语言恰好在这三件事上同时给分。
这就是我在 AI 时代推荐它的原因:不是因为它比谁强,而是因为它把这三件事的成本都压得很低,并且允许我用一句话描述、让 AI 落笔、由编译器裁决、由自检收口。
Rust 走的也是这条路。多一个同方向的答案,对写代码的人是好事。