Ink:用 React 写命令行界面

📅 2026/7/2 20:17:51 👁️ 阅读次数 📝 编程学习
Ink:用 React 写命令行界面

文章目录

  • Ink:用 React 写命令行界面
    • 1、 解决什么问题
    • 2、 哪些项目在用它
    • 3、 怎么用
    • 4、 核心组件
    • 5、 Hooks
    • 6、 测试
    • 7、 上手建议

Ink:用 React 写命令行界面

Ink 在 GitHub 上已经拿到 39K Star 了。

这个项目做的事情很直接:让你用 React 的方式来写命令行工具。你在浏览器里用 React 怎么写组件,用 Ink 在终端里就怎么写。

1、 解决什么问题

写命令行工具,界面部分一直是个麻烦事。

终端不像浏览器有 DOM,没有 CSS,布局全靠手动算空格和换行。想做个进度条、表格、或者多列布局,要么用字符画硬拼,要么找一个封装好的库,然后被它有限的 API 绑死。

Ink 换了个思路:把终端当成渲染目标,接入 React 的组件体系。你写的还是 JSX,用的还是 useState、useEffect 这些 hooks,只不过最终输出到的是终端而不是浏览器窗口。

底层用的是 Facebook 开源的 Yoga 引擎来做 Flexbox 布局,CSS 里的那些对齐、间距、方向属性在终端里全部生效。不用再去数空格和换行了。

2、 哪些项目在用它

判断一个开源项目靠不靠谱,看谁在用就知道了。

Claude Code 是 Anthropic 出的 AI 编程工具,命令行界面就是用 Ink 搭的。Google 的 Gemini CLI 同样如此。GitHub Copilot CLI、Shopify CLI、Cloudflare 的 Wrangler、Prisma、Gatsby 这些项目也都在用。

一个库能同时被 Anthropic 和 Google 选中做自家 CLI 产品的底层,说明它在稳定性和可维护性上是过了关的。

除了大厂的 AI 工具,还有很多社区项目也在用。Shopify 用它做电商平台的命令行管理工具,Cloudflare 用它做 Workers 的部署工具 Wrangler,Prisma 用它做数据库 ORM 的交互界面。从开发工具到电商平台,从云服务到数据库,Ink 的应用场景比想象中要广。

3、 怎么用

安装:

npminstallink react

写一个最简单的计数器:

import React, {useState, useEffect} from 'react'; import {render, Text} from 'ink'; const Counter = () => { const [counter, setCounter] = useState(0); useEffect(() => { const timer = setInterval(() => { setCounter(prev => prev + 1); }, 100); return () => clearInterval(timer); }, []); return <Text color="green">{counter} tests passed</Text>; }; render(<Counter />);

这段代码如果你写过 React,一眼就能看懂。没有新概念,没有新语法,React 的知识直接复用。

4、 核心组件

Ink 提供的组件不多,但覆盖了终端 UI 的主要场景。

<Text>负责文字渲染,支持颜色、粗体、斜体、下划线、删除线,底层用的是 chalk。<Box>是布局容器,你在 CSS 里用过的 flexDirection、justifyContent、alignItems、padding、margin 这些属性都能直接用。<Newline>插入换行,<Spacer>填充剩余空间,<Static>渲染不需要更新的内容,适合放日志这种只增不改的信息。

所有文字必须包在<Text>里,<Box>不能嵌套在<Text>里。记住这两条规则就不会踩坑。

5、 Hooks

Ink 提供了一组专用 hooks。

useInput监听键盘输入,拿到用户按了哪个键。useApp控制应用生命周期,可以主动退出程序。useFocus管理焦点,让组件能响应方向键切换。useWindowSize获取终端窗口尺寸,窗口大小变了组件会自动重渲染。useStdinuseStdout可以直接操作标准输入输出流。

这些 hooks 的命名和用法跟 React 生态保持一致,上手成本很低。

6、 测试

Ink 内置了测试支持。它提供了一个render方法返回的对象,上面有lastFrame()rerender()等方法,可以直接断言组件的输出文本,不需要启动真实的终端进程。

这对写 CLI 工具来说是个实际的好处:终端程序以前很难做自动化测试,要么靠人眼看着对不对,要么写一堆 mock 来模拟输出。Ink 把这个问题解决了,组件的渲染结果可以直接拿来断言。

7、 上手建议

create-ink-app脚手架最快:

npx create-ink-app my-ink-cli

加 TypeScript:

npx create-ink-app--typescriptmy-ink-cli

如果你之前写过 React,Ink 的学习曲线很平。它没有引入新的编程范式,只是把渲染目标从浏览器换成了终端。你需要额外了解的只有几个终端特有的属性,比如<Box>的 borderStyle 和<Text>的 color。

对于想用 Node.js 写命令行工具,又不想在终端布局上花太多时间的人来说,Ink 是一个实际可用的选择。它把 React 生态的组件化、状态管理、测试能力完整搬到了终端里,不用学新东西,直接用已有的 React 知识就能开工。

写命令行工具,又不想在终端布局上花太多时间的人来说,Ink 是一个实际可用的选择。它把 React 生态的组件化、状态管理、测试能力完整搬到了终端里,不用学新东西,直接用已有的 React 知识就能开工。