跳到主要内容

Ink 终端渲染器

Claude Code 使用 React + Ink 在终端中渲染复杂的交互式 UI。Ink 是一个将 React 组件渲染到终端的框架,让 Claude Code 可以用声明式的方式构建终端界面。

为什么用 React 渲染终端?

传统终端 UI 通常用 ncurses 或纯文本输出。Claude Code 选择 React + Ink 的原因:

  1. 组件化 — 144 个组件组成了完整的 UI 系统
  2. 声明式 — 描述 UI "应该是什么样",而不是"如何绘制"
  3. 状态管理 — React 的 useState/useEffect 天然适合管理 UI 状态
  4. Flexbox 布局 — Ink 支持 Flexbox,在终端中也能做复杂布局
  5. 生态复用 — 可以利用 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, justifyContent
  • padding, margin
  • borderStyle, borderColor
  • width, height, minWidth, minHeight