ink-markdown-es:为 Ink 打造的高性能 Markdown 渲染组件
2026年1月18日 23:57
前言
最近在用 Ink + LangChain deepagents开发一个轻量的 CLI Coding Agent,遇到了一个棘手的问题:如何在命令行中优雅地渲染 Markdown 内容?
调研了现有方案后发现,ink-markdown 虽然是大家常用的库,但:
- 我使用的 bun 来管理项目,而 ink-markdown 不支持 ES Module,无法开箱即用
- 太老了,不支持 ink 最新版本以及其依赖的 React 19
所以,我基于 marked 重新实现了一个:ink-markdown-es
特性
- 纯 ESM 支持:完全拥抱现代 JavaScript 生态
-
高性能渲染:使用
memo和useMemo优化,每个 block 独立缓存(Inspired by prompt-kit) -
灵活的自定义:支持
styles和renderers两种自定义方式 - 完整的 Markdown 支持:标题、列表、代码块、表格、引用、链接等
- TypeScript 友好:完整的类型定义
安装
npm install ink-markdown-es
# 或者
pnpm add ink-markdown-es
# 或者
bun add ink-markdown-es
基础用法
import Markdown from "ink-markdown-es";
import { render } from "ink";
const content = `
# Hello World
这是一段**加粗**和*斜体italic*文字。
## 代码示例
\`\`\`javascript
const greeting = "Hello, Ink!";
console.log(greeting);
\`\`\`
- 列表项 1
- 列表项 2
- 列表项 3
`;
render(<Markdown>{content}</Markdown>);
![]()
自定义渲染器
你可以完全自定义任意 Markdown 元素的渲染方式:
import Markdown from "ink-markdown-es";
import { Box, Text } from "ink";
render(
<Markdown
showSharp
renderers={{
h1: (text) => (
<Box padding={1} borderStyle="round" borderDimColor>
<Text bold color="greenBright">
{text}
</Text>
</Box>
),
code: (code, lang) => (
<Box borderStyle="single" padding={1}>
<Text color="yellow">{code}</Text>
</Box>
),
}}
>
{content}
</Markdown>
);
性能优化原理
在处理流式输出(如 AI 对话)时,Markdown 内容会频繁更新。传统方案每次更新都会重新渲染整个组件树,造成性能问题。
ink-markdown-es 的优化策略:
-
Block 级别缓存:使用
useMemo缓存 marked 的词法分析结果 -
Block 级别 memo:每个 Markdown block 都是独立的
memo组件 - 智能对比:只有 block 内容变化时才会触发重新渲染
在流式输出场景下,已经渲染的 block 不会重复渲染,只有新增的内容才会被处理。
Props 说明
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| children | string | - | Markdown 文本内容 |
| id | string | - | 组件唯一标识,适用于 AI 场景区分不同消息 |
| styles | BlockStyles | {} | 自定义样式配置 |
| renderers | BlockRenderers | {} | 自定义渲染器 |
| showSharp | boolean | false | 是否显示标题的 # 符号 |
适用场景
- CLI AI 助手:流式输出 Markdown 格式的 AI 回复
- 终端文档查看器:在命令行中渲染 README 等文档
- 交互式终端应用:任何需要展示富文本的 CLI 工具
库信息
GitHub: github.com/miownag/ink…
如果这个库对你有帮助,欢迎给个 Star 支持一下!有任何问题或建议,也欢迎在评论区交流~