Ink 终端渲染器
Claude Code 使用 React + Ink 在终端中渲染复杂的交互式 UI。Ink 是一个将 React 组件渲染到终端的框架,让 Claude Code 可以用声明式的方式构建终端界面。
为什么用 React 渲染终端?
传统终端 UI 通常用 ncurses 或纯文本输出。Claude Code 选择 React + Ink 的原因:
- 组件化 — 144 个组件组成了完整的 UI 系统
- 声明式 — 描述 UI "应该是什么样",而不是"如何绘制"
- 状态管理 — React 的
useState/useEffect天然适合管理 UI 状态 - Flexbox 布局 — Ink 支持 Flexbox,在终端中也能做复杂布局
- 生态复用 — 可以利用 React 生态的 Hook 和模式
渲染架构
React 组件树
↓
Ink 渲染器 (src/ink/, 50+ 文件)
↓
Yoga 布局引擎 (Flexbox)
↓
ANSI 转义码生成
↓
终端输出
核心渲染流程
// 入口文件 main.tsx 中启动 Ink 渲染
import { render } from 'ink';
const { waitUntilExit } = render(
<App
messages={messages}
tools={tools}
onSubmit={handleSubmit}
/>
);
await waitUntilExit();
自定义 Ink 扩展
Claude Code 对 Ink 进行了深度定制(src/ink/,50+ 文件):
布局增强
- 自定义的文本换行算法
- 终端宽度自适应
- 滚动区域管理
- 焦点管理系统
渲染优化
- 差量更新(只重绘变化部分)
- 流式内容渲染(LLM 输出时逐字显示)
- 大文本块的分批渲染
终端适配
- 256 色 / True Color 支持
- 终端能力检测
- 窗口大小变化响应
全屏界面
src/screens/ 包含 3 个全屏界面:
| 屏幕 | 用途 |
|---|---|
| Doctor | 环境诊断界面 |
| REPL | 主交互循环 |
| Resume | 会话恢复选择 |
样式系统
// Ink 的样式类似 CSS Flexbox
<Box
flexDirection="column"
borderStyle="round"
borderColor="green"
padding={1}
margin={1}
>
<Text bold color="cyan">标题</Text>
<Text dimColor>描述文本</Text>
</Box>
支持的样式属性:
flexDirection,alignItems,justifyContentpadding,marginborderStyle,borderColorwidth,height,minWidth,minHeight