用 Rust 和 gpui 写桌面端:现在只有一个外壳和四个面板
先把状态说清楚,否则下面每一句都会被误读。
本文描述的是 OpenCut 重写版仓库当前的代码结构与官方 README 声明的路线图。该版本尚未发布,Editor API、插件体系、MCP server、无头模式等均为官方声明的计划,我们没有见到可用实现。核对日 2026-08-09。
OpenCut 现在有两个仓库,状态完全不一样,混在一起讲就是灾难:
| 主仓(重写版) | classic(旧版) | |
|---|---|---|
| 仓库 | OpenCut-app/OpenCut | OpenCut-app/opencut-classic |
| star | 81917 | 213 |
| 是否归档 | 否 | 是,已归档、不再维护 |
| 最后推送 | 2026-08-05 | 2026-05-17 |
| 线上站点 | 将来落在 new.opencut.app | opencut.app 今天跑的就是它 |
(以上为 GitHub API 元数据快照,核对日 2026-08-09。star 数只是当天的一个计数,不能由它推出任何关于质量、稳定性或适用性的结论。)
主仓 README 的 Status 段第一句原文是 “OpenCut is being rewritten from the ground up.”——正在从头重写。README 紧接着说,旧版本仍在 opencut-app/opencut-classic,那才是今天该用的那个。所以本文谈的这个 Rust 桌面端,属于那个还没发布的重写版;你现在在 opencut.app 上看到的东西,跟它没有关系。
一、apps/desktop/src/ 目录里到底有什么
我们把重写主仓克隆到本地,实读了 apps/desktop/ 这个目录。全部内容如下:
apps/desktop/
├── Cargo.toml
├── moon.yml
├── README.md
└── src/
├── main.rs
├── shell.rs
├── theme.rs
├── components/ (badge.rs, button.rs, context_menu.rs, label.rs,
│ mod.rs, resizable.rs, separator.rs)
└── panels/ (browser.rs, inspector.rs, preview.rs, timeline.rs, mod.rs)
数一下:三个顶层源文件,components/ 下七个文件、panels/ 下五个文件,两个目录里各有一个 mod.rs 只负责声明模块。就这些。
components/ 里除 mod.rs 外的六个名字——badge、button、context_menu、label、resizable、separator——是任何一个 GUI 工具包都要先补齐的基础件,不是剪辑软件特有的东西。panels/ 下的四个名字 browser、inspector、preview、timeline,确实勾勒出一个典型编辑器的四区布局:素材浏览、属性检视、画面预览、时间轴。
但这里要卡一句:这是文件名给的印象,不是我们见过的界面。 我们没有编译、没有运行过任何版本的 OpenCut,不知道这四个文件里各写了多少行、渲染出来是什么样、能不能拖动一段素材。把文件名当成功能清单,是读开源仓库时最常见的自我欺骗。文件名告诉你的只有一件事:作者打算把界面切成这四块。
二、根 Cargo.toml 里那行被注释掉的 crates/*
比目录树更有信息量的是重写主仓根目录的 Cargo.toml(下面这段配置、以及本节和第三节涉及的所有文件,全部来自重写版仓库 OpenCut-app/OpenCut,classic 那边的目录结构完全是另一回事):
[workspace]
resolver = "3"
members = [
'apps/desktop',
# 'crates/*',
]
[workspace.package]
version = "0.1.0"
edition = "2024"
license = "MIT"
[workspace.dependencies]
gpui = "0.2.2"
三处值得逐个念:
一是 members 里只有 apps/desktop 一个成员,crates/* 被注释掉了。 README 承诺的路线图里有一条是「桌面、移动、浏览器共用一套代码库(Rust 核心)」。那个 Rust 核心,按 Cargo workspace 的惯例应该以若干个 crate 的形式躺在 crates/ 下,再由三端各自引用。现在这一行还是注释。也就是说:「Rust 核心」这条路线图,在这个仓库里还没有对应的 crate。 这不是我们的评价,是 Cargo.toml 的字面内容。
二是 version = "0.1.0"。 workspace 级的包版本号停在 0.1.0。
三是 edition = "2024"。 这条对你有直接影响:edition 2024 需要足够新的 Rust 工具链,你不能拿一个老版本 rustc 去碰它。仓库自己也把版本钉死了,下一节说。
另外,我们看到的 [workspace.dependencies] 段里只声明了 gpui = "0.2.2" 一项。gpui 是 Zed 编辑器所用的那个 Rust GUI 框架,这里只陈述依赖事实——我们没有编译过,不谈它的性能、渲染效果或者跟别的 GUI 方案怎么比。
三、工具链是 proto + moon,版本全部钉死
重写主仓不用你手动装 Node/Bun/Rust,它用 proto 管工具版本、用 moon 跑任务。README 给的步骤是先装 proto:
# Linux, macOS, WSL
bash <(curl -fsSL https://moonrepo.dev/install/proto.sh)
# Windows PowerShell
irm https://moonrepo.dev/install/proto.ps1 | iex
Windows 上如果 shim 跑不起来,README 给的处置是为当前用户允许本地脚本:
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
然后在仓库根执行 proto use,它会按 .prototools 里钉住的版本装工具。.prototools 全文只有三行有效内容:
moon = "2.3.3"
bun = "1.3.11"
rust = "1.97.0"
文件里那句注释写的是:proto 在 workspace 范围内钉住工具版本,每个开发者和 CI 机器都自动拿到完全相同的版本。这个做法本身跟 OpenCut 无关,但它解释了一件事:你要编译这个桌面端,Rust 版本不是「你机器上那个」,而是 1.97.0。 如果你习惯用 rustup 手动切换,这里的心智模型要换一下——版本归仓库管,不归你管。
跑起来的命令是 moon 任务:
moon run web:dev # localhost:5173
moon run api:dev # localhost:8787
moon run desktop:dev # 见 apps/desktop/README.md
注意 desktop:dev 那行,README 没给端口,而是指向 apps/desktop/README.md——桌面端是原生程序,本来也没有端口这回事。顺带记一下这三个数:重写版 web 起在 5173、api 起在 8787,而 classic 那个 Next.js 应用起在 3000。三个端口分属两个不同代码库,别记串。
四、这套结构能让你自己做哪几个判断
这才是读目录树的意义。下面每一条都给了可复核的动作,不用信我。
判断一:现在想剪片子,要不要去主仓? 不要。README 自己写了旧版本才是今天该用的那个,opencut.app 跑的仍然是 classic。主仓 apps/desktop/src/ 十几个文件、crates/* 还注释着,你 clone 下来编译,得到的也不会是一个能用的剪辑器。
判断二:怎么知道「Rust 核心」到位了没有? 去看根 Cargo.toml 的 members。# 'crates/*' 这一行什么时候取消注释、crates/ 目录下什么时候出现真的 crate,什么时候才谈得上有一个可被三端共享的核心。这是一条你自己一眼能查、不用等任何人发通稿的指标。
判断三:桌面端和 web 端现在是不是「一套代码」? 不是。重写版 web 端走的是 TanStack Router / TanStack Start + Vite + Cloudflare 那一套 TypeScript 栈,桌面端走的是 Rust + gpui,两边现在各写各的,中间没有共享 crate。「跨三端一套代码库」是 README 列的计划,不是现在的状态。
判断四:想读 gpui 的入门代码,这个目录合不合适? 它的规模摆在那儿:main.rs + shell.rs + theme.rs 加七个基础组件。合不合适你自己判断,但请带着「这是一个进行中的、未发布的仓库」这个前提去读,别把它当成成熟范例。另外 README 明说:架构还在设计中,他们还没准备好接受外部贡献(原文 “We’re not set up to take outside contributions yet while the architecture is being designed.”)。你读出问题也别急着提 PR,那个仓库现在不收。 想跟进可以去 Discord 或者开 issue。
判断五:路线图上那几条能不能写进你的技术选型文档? 不能。Editor API、一等公民的第三方插件、跨三端共用一套代码库、面向 AI agent 的 MCP server、无头模式(自动化与批量渲染)、编辑器内置的脚本标签页——这几条全部是重写主仓 README 里「即将到来」段落列出的内容,是官方声明的计划,重写版本身尚未发布。我们没有见到任何一条的可用实现,也没有在 apps/desktop/ 或根 Cargo.toml 里看到任何与之对应的模块。 如果你的方案依赖其中任意一条,现在没有东西可依赖。
五、什么情况下本文的结论会失效
三种情况,都很直白:
一是主仓推了新提交。核对日是 2026-08-09,最后推送记录是 2026-08-05,这是个活跃仓库,目录随时会变。你照着本文去看目录,发现文件多了几个,是正常的——重新数一遍就是。
二是 crates/* 那行注释被去掉了。那说明第二条判断的答案变了,本文关于「还没有 Rust 核心 crate」的陈述就过期了。
三是重写版发布、或者 new.opencut.app 上线接管。README 只说「直到它准备好」,没有给任何时间表,我们也不做预测。
最后重复一遍最容易搞混的事:classic 那个仓库已归档、不再维护,但 opencut.app 线上跑的仍然是它;重写主仓活跃在推进,但还没有发布。这两句话同时成立,讲 OpenCut 的时候每次都得说清楚指的是哪一个。
延伸阅读
- 从 0.1.0 到 0.3.0:官方 changelog 记了些什么
- 重写版的栈:TanStack Start、Vite、Cloudflare 与 Rust gpui
- Editor API、插件、MCP server、无头渲染:五条承诺目前都还是承诺
本文依据 OpenCut 官方仓库(github.com/OpenCut-app/OpenCut 与已归档的 github.com/OpenCut-app/opencut-classic)的 README、.prototools、moon.yml、Cargo.toml 与 apps/desktop/ 目录整理,核对日 2026-08-09。本文内容为仓库源码与文档口径,我们没有编译或运行过任何版本的 OpenCut。
本文描述的是 OpenCut 重写版仓库当前的代码结构与官方 README 声明的路线图。该版本尚未发布,Editor API、插件体系、MCP server、无头模式等均为官方声明的计划,我们没有见到可用实现。核对日 2026-08-09。
许可条款请以官方 LICENSE 原文为准,本文不构成法律意见。