大家好,我是 OxideTerm 的作者。之前在 NS 发过几次帖,老读者可能还记得 1.4.2 那篇末尾提了一嘴「在往 GPUI 原生迁移,不知道什么时候能写完」。我现在写完了。2.0 正式发布。OxideTerm确实成为了原生软件。

一、为什么换引擎——WebView 的上限到了
Tauri 是个好东西,1.x 版本的功能也是实实在在跑通的。但随着终端能力越来越多,我逐渐碰到了 WebView 很难绕开的限制:功能可以继续加,渲染开销和底层可控性却很难再往前走。举几个当时让我头疼的具体场景:
- 大日志刷屏:
yes或者cat一个大文件时,xterm.js 的 WebGL/Canvas 渲染、Rust 与 JavaScript 之间的数据传递会一起承受压力,终端 UI 容易掉帧 - 浅色主题锯齿:xterm WebGL 渲染器在浅色背景下有渲染缺陷——不是配置问题,是底层就这样,我尝试过注入一些参数去优化,但是没用。
- 空载 320MB 内存:一个终端工具吃掉这些,虽然能用,但总觉得不对。即使没有打开会话,WebView、DOM 和 JavaScript 运行时的固定开销依然存在
- linux 兼容性问题:好多反馈 Linux 环境下打开就崩溃
继续局部优化当然还能挤出一些空间,但已经很难改变整体架构带来的固定成本。所以我做了一个决定:把整个应用重写,换成 GPUI。它是 Zed 编辑器使用的 Rust 原生 GPU UI 框架。新版不再使用 WebView 和 JavaScript UI 层,终端状态、界面组件与渲染逻辑都留在 Rust 这一侧。
换完之后,macos空载内存从 320MB 左右降到了 80MB 出头,windows则从 182.4MB 下降到了 23.5MB. 我自己看了都觉得很夸张。这不是某一个参数调优的结果,而是移除 WebView、DOM 和 JavaScript 运行时之后,整体架构变化带来的结果,现在你可以用更低的内存来驱动你的 SSH 工作。

除了内存,原生重写还带来了三个直接变化:
- 数据链路更短:以前终端数据要从 Rust 后端序列化后经过 IPC 传给 JavaScript,再交给 xterm.js 渲染。现在由
alacritty_terminal维护终端状态,GPUI 直接构建并渲染界面,省去了跨语言序列化和 IPC。 - 视觉效果更可控:在我们维护的 GPUI fork 中,亚克力模糊和毛玻璃背景分别接入了 macOS 的 Metal、Windows 的 DirectX,以及 Linux 上基于 wgpu 的 Vulkan/OpenGL 渲染路径,在控制效果的同时降低额外渲染开销。
- 界面更统一:组件、间距、圆角和动画都由同一套 Rust UI 实现,不再受不同系统 WebView 渲染差异的影响。
顺带也把整个应用的外观翻了一遍——Tauri 版界面说实话还是草稿水平,间距、配色和圆角都不统一。这次重新整理了视觉风格和动画,大日志刷屏时的 UI 掉帧,以及不同系统 WebView 带来的渲染差异也得到了显著改善。

二、从 Webview 到原生,挑一点最想说的
从 1.4.2 到现在干了太多事,有功能的更新,也有架构大换血,就不完全展开了。挑三个我觉得最代表性的。
终端:终于不是「在浏览器里跑模拟器」了
之前的核心是 xterm.js。现在改由 alacritty_terminal 负责终端解析和状态维护,再由 GPUI 完成界面渲染,省去了 Rust 与 JavaScript 之间的序列化和 IPC。大输出场景的数据链路因此更短,cat 一个几万行的日志文件时,UI 在持续输出压力下的表现也明显稳定了。
除此之外,我们还在新的终端渲染层里单独实现了 Sixel 和 Kitty 图形协议支持。它不是换用 alacritty_terminal 自动获得的能力,但借着这次原生重写终于接进来了:现在可以使用 kitten icat、img2sixel,或者支持图形协议的 yazi,直接在 SSH 会话里预览图像。
说白了就是:终端从一个“在浏览器沙箱里显示字节的窗口”变成了一个真正围绕命令和输出组织、也更容易继续扩展的原生工作区。

Host Tools:把 SSH 从“一个终端”变成“一个工作区”
当然,我们也补上了 RDP 和 VNC 的基础支持,其中 RDP 基于纯 Rust 的 IronRDP,VNC 也直接内置在应用中。但这次重写,我个人投入精力最多、也觉得最有价值的,其实是 Host Tools——就在连接旁边的侧边栏里。
这套工具的思路是消除上下文切换。传统的 SSH 工作流是:你开一个终端,敲 htop 看进程,想看 Docker 再开一个终端敲 docker ps,想看日志再 tail -f。你的屏幕被一堆终端窗口占满,信息是割裂的。
Host Tools 想解决的就是这个问题。你正在终端里看着日志输出,同时点开旁边的 Docker 面板重启一个容器,然后切换到进程列表看看 CPU 占用有没有下来——整个过程你都不需要离开 OxideTerm 的窗口,信息是聚合的、联动的。
目前 Host Tools 已经覆盖了:进程管理、Docker 容器、tmux 会话、systemd 服务启停、日志流、网络端口监听、磁盘用量。所有这些信息都通过你现有的 SSH 连接实时采集,不需要在服务器上装任何 agent。这才是我们理解的“SSH 工作区”——不只是一个敲命令的地方,而是一个围绕远程主机的集成驾驶舱。
云同步从插件变内置
Tauri 版的时候云同步是作为一个可选插件提供的,很多用户的反馈是“不知道有这个功能”或者“安装太麻烦”。这次重写,我们把云同步直接变成了设置里的一个核心功能,让它成为“一等公民”。
更重要的是,我们坚持了“隐私优先”和“用户自有数据”的原则。你可以选择用 WebDAV(包括自建的 Nextcloud/ownCloud)、S3 兼容对象存储、OneDrive、Google Drive、Dropbox 或者 GitHub Gist 来同步你的连接、设置和密钥。同步内容会在上传前于本地加密,OxideTerm 也没有一个用于保存用户数据的中央服务器。我不想做注册账号、把数据存在厂商服务器上的商业工具。坚持数据隐私是底线。
我的思路很简单:同步功能应该像本地保存一样自然,用户不需要为此信任一个新的商业实体,也不需要为此付费。

其他:这次一起带到 2.0.0 的还有
- 独立 CLI:不启动桌面应用也能完成环境诊断、配置校验、连接与端口转发管理、云同步、便携包导入导出和问题报告生成,方便接进脚本与 CI。
- WASM 插件沙箱:插件运行在
wasmtime沙箱中,通过按能力授权的宿主 API 扩展标签页和设置,而不是直接接触应用内部状态。 - X/Y/ZMODEM 文件传输:在终端里识别传输协议后,可以直接选择本地文件进行收发,不需要为了传一个文件再切到单独的面板。
- 连接生命周期收归进程内:终端、SFTP、端口转发和重连不再分散在前后端两侧,而是共享同一套 Rust 连接与恢复链路。
- SFTP性能增强:russh-sftp很多的实现性能比较一般,我自己vendor并改造,让sftp上传下载速度取得了显著的进步。
- 丰富的动画效果,更加统一的视觉语言,希望能让你看着觉得这是个现代软件。
- 对数据隐私的重视依然不变,无遥测,无订阅。

三、关于收费
最开始做 OxideTerm 的动机特别简单——市面上 SSH 工具收费的太多了。Termius $15/月,国产的一些软件也跟着收。我自己不想交这个钱,正好也想学点东西,就开始写了。
现在还在读研,趁自己还有学生时代的心气,还是希望能继续做下去。至少在现阶段,OxideTerm 桌面版会继续免费开源,采用 GPL-3.0。
四、写在最后
说实话,做这个项目本来也只是1月自己一时兴起,觉得连 autodl 服务器太麻烦,想着自己能不能搓点小工具出来方便自己的工作流。那个时候听说 Rust 很好,于是尝试了 Rust + Egui ,何奈当时什么也不懂,ai 写的也不好,只能放弃转向 Tauri。没想到自己越做越来劲,就这么一直维护下来,直到4月份登上了阮一峰周刊,项目在一天内涨了 100 多 star ,nodeseek也有人发现了这个项目。发现一个新的纯 Rust 编写的 ssh 客户端这之后,我就一直没停下对项目的维护。
有人可能觉得我在5月份到7月份更新速度放慢了,那段时间确实:一遍维护 Tauri 版本的稳定性,一遍从 0 开始给项目重写 GPUI 版本,AI 复刻外观,我一点一点监工过来,直到如今把 GPUI 版本推出,功能是 Tauri 版本的超集,同时性能与内存表现也更优,其中困苦不必多说:很多东西说起来简单,做起来就难了,即便现在大家基本都用 AI 写代码。但我很庆幸我能坚持过来,让 OxideTerm 浴火重生,而不是在 Tauri 架构下继续缝缝补补。
目前 1000+ star,全靠社区大家的支持涨上来的。如果你日常连一堆服务器,可以试试。觉得好用点个 Star,有 bug 提 Issue。祝愿大家都有趁手的 SSH 工具,和物美价廉的小鸡。
GitHub:https://github.com/AnalyseDeCircuit/oxideterm
官网: https://oxideterm.app/
安全审查报告:OxideTerm
审查范围:整个代码库(~85 个 crate,agent 独立二进制文件,GitHub Actions 工作流,构建脚本)。未发现后门、数据外传、远程控制机制或可疑的加密字段。
网络通信
所有的网络外发请求都是用户配置的、有文档记载的端点:
github.com/AnalyseDeCircuit/oxideterm/releases获取清单。下载的包使用嵌入的 integrity.rs 中的 minisign 公钥进行签名验证。github.com/AnalyseDeCircuit/oxideterm-wasm-runtime/releases获取。没有遥测、分析、崩溃报告或第三方追踪系统。 i18n 字符串中明确说明了这一隐私承诺。
加密
所有加密都有合法的安全目的:
36E19D6992B57EBB)zeroize::Zeroizing[REDACTED]唯一被硬编码的密钥是更新公钥 —— 这是验证签名更新所必需的,属于标准做法。
代理 / 远程执行
agent/ 目录是 OxideTerm 远程代理:一个独立的二进制文件,通过 SSH 通道在远程主机上运行,接收 stdin/stdout 上的 JSON-RPC 命令。功能包括文件读写、grep、符号索引和目录列表。它不发起任何网络连接 —— 仅在 stdin/stdout 上响应。依赖项仅有
serde、regex、sha2、walkdir—— 不含 HTTP 或套接字。传输层通过 SSH
exec通道传递:transport.rs。自动启动 / 持久化
autostart.rs 使用标准的 OS 机制:Windows 注册表
Run键、Linux XDG autostart.desktop、macOSSMAppService。用户可配置、透明、可逆。无隐藏持久化。插件系统
插件以 WASM 沙箱运行(
wasmtime)。它们由用户手动安装。无自动下载或执行。constants.rs 中对包大小(50 MB)、解压后大小(100 MB)和条目数(2048)有显式限制。SSH 主机密钥
host_key.rs 实现了带有 Unknown/Changed/Verified 状态的 TOFU(首次使用即信任)主机密钥验证。主机密钥缓存在内存中,有效期为 1 小时。未发现服务器认证绕过。
供应链
Cargo.toml 包含 deny.toml(cargo-deny 配置),可防止已知的有漏洞依赖项。所有依赖项均来自标准 crates.io。未发现可疑或混淆的依赖项。
结论
未发现后门、数据外传或可疑的加密字段。 代码库干净,隐私意识强(AI 请求前清理机密,无遥测),加密使用得当且目的明确。网络通信仅在用户配置的情况下发生,且配置了签名验证,以防供应链攻击。
@usermeme #29
这个其实早就做了,但是没接入到 UI ,会有的,会有的,写出来我自己也爱用
@richno #36
让ai调查了一下:
所以卡顿倒也不是性能不行(原生软件,不太可能性能比webview差),是windows渲染链路的问题,我看看怎么修改一下项目的渲染引擎的源码吧
@fsxitutu #38
你好,兄弟,有的,很有机会。你看我https://github.com/AnalyseDeCircuit/fernomade
顶大佬!
试用了一下,整体很喜欢,完成度很高,很厉害。不过有几个迷你建议:
厉害厉害
这个行,现在跨端的好多都用Electron太臃肿了
ICON很好看,简洁大气。
支持
支持
围观
支持一波
太厉害了