今天在 GitHub Trending 上看到一个脑洞非常大的项目:terminal-browser,它把一个完整的 Chromium 浏览器直接嵌入了你的终端窗口,让你在命令行里也能上网冲浪。这个想法听起来有点反常识——浏览器和终端,明明是两个世界的东西,怎么就凑到一起了?
一、项目概述
terminal-browser 由 zenbu-labs 开发,核心目标是用终端的图形协议渲染真实网页,实现"在终端里开浏览器"的体验。它不是一个模拟器或文本浏览器,而是一个货真价实的 GUI 浏览器,只不过输出载体换成了支持 kitty graphics 协议的终端。
目前支持以下终端:
- ghostty(macOS 原生终端,高性能)
- kitty(跨平台 GPU 加速终端)
- cmux(终端复用器)
- VSCode 集成终端
核心特性一览:
- 完整 Chromium 内核,渲染效果与桌面浏览器一致
- 支持 SSH 远程代理,可访问远程机器的 localhost 网站
- 开发者工具(F12 / cmd+shift+i)
- 命令面板(cmd+p / cmd+k)
- 分屏模式(
--split right) - App Mode:用浏览器技术构建终端 App
安装方式极其简单:
curl -fsSl https://terminal-browser.sh/install | bash
使用方式同样直观:
terminal-browser # 直接启动浏览器
terminal-browser open <url> # 打开指定网址
terminal-browser --split right # 在右侧分屏打开
terminal-browser open --ssh user@host <url> # SSH 代理访问远程网站
terminal-browser ls # 列出当前打开的浏览器实例
二、技术原理
2.1 整体架构
terminal-browser 的架构分为三层,从下到上依次是:
Layer 1 — Electron Offscreen Rendering(浏览器渲染层) terminal-browser 使用 Electron 的 Offscreen Rendering API,直接在 GPU 上渲染 Chromium 页面,而不创建传统意义上的窗口。像素数据从 GPU 显存直接读取,完全绕过了系统窗口管理器。
// 核心渲染逻辑(简化自源码)
const { app, BrowserWindow } = require('electron');
app.on('ready', () => {
const win = new BrowserWindow({
webPreferences: {
offscreen: true, // 关键:开启 offscreen 模式
}
});
win.loadURL('https://example.com');
// 像素由 Electron 自动渲染到离屏画布
});
Layer 2 — Rust 图形引擎(像素传输层) 渲染出的像素通过 Rust 编写的图形引擎传输到终端。引擎的核心职责是:
- 从 Electron 读取 GPU 渲染的像素帧
- 将像素编码为 kitty graphics 协议的数据块
- 通过终端的图形协议将像素绘制到屏幕上
kitty graphics 协议是一种将二进制图像数据嵌入终端输出的协议。协议支持 PNG/RGBA 格式,terminal-browser 使用 RGBA 直接传输像素:
# kitty graphics protocol 简化示意
\x1b_G...<image data>...\x1b\\
Layer 3 — React UI + Swift 输入捕获(交互层) 浏览器外壳的 UI(地址栏、标签栏、工具栏)使用 React 实现,通过自定义 React Renderer 直接绘制到 Rust 引擎的共享 Canvas 上。
用户输入(键盘、鼠标、触控)的捕获则是一个难点——终端本身并不能捕获所有输入事件(如触控板滚动)。terminal-browser 通过一个后台 Swift App 来全局监听输入事件,再转发给 Chromium:
终端输入事件 → Rust 引擎 → Electron Chromium (synthetic events)
↑
Swift 后台 App 监听系统级输入 → 转发到 Electron
2.2 SSH 远程代理的实现
SSH 模式是 terminal-browser 的一大亮点。常规 SSH X11 转发的问题是:每个像素帧都要通过网络传输,体验很差。
terminal-browser 的 SSH 模式采用本地渲染 + 远程请求代理的策略:
terminal-browser --ssh user@host <url>
工作原理:
- Chromium 浏览器实例在本地运行并渲染
- 网页发出的所有 HTTP/HTTPS 请求通过 SSH 隧道代理到远程服务器
- 远程服务器充当代理,访问本地无法访问的资源(如远程 dev 环境)
这样一来,localhost、远程内网服务都可以在本地浏览器中完美呈现,同时保留了 Chromium 的完整渲染能力。
2.3 App Mode:从浏览器到终端 App
terminal-browser 的 App Mode 让它变成了一个用浏览器技术构建终端应用的框架:
terminal-browser open https://my-app.com \
--app-mode \
--no-toolbar \
--no-frame \
--allow-clipboard-read
结合 --preload(注入自定义 JavaScript API)和 --main-script(Node.js 主进程脚本),可以实现:
- 与终端命令行深度集成的 Web 应用
- 使用 Web 技术栈开发的终端原生 UI
三、安装与快速开始
环境要求
- macOS 或 Linux
- 支持 kitty graphics 协议的终端(推荐 ghostty 或 kitty)
- Node.js(用于 Electron)
- Rust(用于图形引擎编译)
- pnpm
安装步骤
官方一键安装脚本(自动检测平台并安装依赖):
curl -fsSl https://terminal-browser.sh/install | bash
手动安装(macOS):
brew install rustup
rustup-init
brew install node pnpm
git clone https://github.com/zenbu-labs/terminal-browser
cd terminal-browser
pnpm install
pnpm build
快速体验
# 启动浏览器
terminal-browser
# 打开指定网站
terminal-browser open https://github.com
# 分屏模式(左侧终端,右侧浏览器)
terminal-browser --split right
# SSH 代理访问远程 localhost
terminal-browser open --ssh myserver.com http://localhost:3000
# 命令面板
# macOS: cmd+p / Linux: ctrl+k
四、使用场景与实战
场景一:AI Agent 的浏览器工具
这是作者最看重的使用场景之一。将 terminal-browser 与 AI 编程 Agent 配合:
# 在终端左侧启动 Agent,右侧启动浏览器
terminal-browser --split right
Agent 可以通过 CLI 接口控制浏览器:
terminal-browser action open https://example.com
terminal-browser action click .btn-submit
terminal-browser action type #search "hello world"
这意味着 AI Agent 可以直接操控真实的浏览器,与传统基于文本解析的方案相比,准确率大幅提升。
场景二:远程开发预览
开发者通常需要预览远程服务器上跑的服务:
# 远程开发服务器跑在 myserver:8080,本地通过 SSH 代理预览
ssh -L 8080:localhost:8080 myserver &
terminal-browser open http://localhost:8080
场景三:终端 App 开发
用 Web 技术栈开发终端原生应用:
terminal-browser open ./dist/index.html \
--app-mode \
--no-toolbar \
--preload=./preload.js
五、常见问题与解决方案
Q1: 终端不支持 kitty graphics 协议怎么办?
terminal-browser 依赖 kitty graphics 协议发送像素帧。如果你的终端不支持该协议,浏览器窗口将无法显示。建议改用 ghostty(macOS,推荐)或 kitty(跨平台)。
# 检查终端是否支持 kitty graphics
# 在 kitty 终端中运行以下命令,如果有图像输出则支持
printf '\x1b_Gi=1\x1b\\'
Q2: SSH 模式下网页加载很慢?
确保使用 --ssh 参数而不是直接 SSH X11 转发。本地渲染 + 远程请求代理的模式可以大幅降低延迟。如果仍然慢,检查网络带宽和 SSH 连接质量。
Q3: 触控板滚动不工作?
默认情况下终端无法捕获触控板事件。terminal-browser 通过 Swift 后台 App 监听系统级触控事件来解决这个问题。如果滚动仍然有问题,检查系统设置中是否授权了终端的辅助功能权限。
Q4: 浏览器字体太小?
使用终端自身的缩放快捷键(ghostty: cmd+=/cmd+-,kitty: ctrl+shift+T/K)调整缩放级别,terminal-browser 会自动适配。
Q5: 如何自定义 App Mode 的主题?
通过 --preload 脚本访问 globalThis.terminalBrowser API:
// preload.js
window.addEventListener('DOMContentLoaded', () => {
if (globalThis.terminalBrowser) {
globalThis.terminalBrowser.onTheme((theme) => {
document.body.style.background = `rgb(${theme.background.join(',')})`;
});
}
});
六、总结
terminal-browser 是一个非常有意思的跨界项目——它不是简单地把浏览器塞进终端,而是用浏览器技术重新定义终端的边界。借助 Electron Offscreen Rendering + kitty graphics 协议 + Rust 图形引擎的三层架构,它实现了在终端里运行真实浏览器的目标,而且体验相当流畅。
最令人眼前一亮的应用场景是 AI Agent + 浏览器工具链:让 AI 直接操控真实浏览器访问网页,比任何文本解析方案都更可靠。随着 AI 编程工具的普及,这个方向可能会成为 terminal-browser 最有价值的落地点。
项目仍在活跃开发中(Roadmap 包括 Chrome 扩展支持和 Design Mode),如果你对终端图形化或 AI + 浏览器方向感兴趣,非常值得一试。