EN

生态选型

为 Node.js CLI 选择本地数据库、颜色、Prompt、任务输出、进度和终端界面工具。

更新于

func 负责命令模型、类型化输入和依赖注入,不限制 CLI 的存储、呈现与交互方式。下面按常见需求整理 Node.js 内置模块和生态功能包,同时标注各自适合的场景,方便在默认推荐和其他可选方案之间比较。

如何阅读对比数据

下载量来自 npm 2026-07-31 至 2026-08-06 的统计,并使用 M(百万)和 K(千)缩写。它可以反映生态采用程度,但其中包含自动化安装和传递依赖安装,不能等同于真实用户数量,也不代表质量排名。

Bundle 数据是在固定示例中使用 esbuild 打包为经过压缩和 Tree Shaking 的单文件 ESM CLI 后,相对基线增加的体积,并四舍五入到整数 KiB。体积只是选型标准之一,不应作为唯一依据。维护活跃度、Node.js 版本要求、ESM/CJS 兼容性、文档质量、API 设计、无障碍支持、测试体验,以及功能包是否符合 CLI 的交互模型都同样重要。对发布体积敏感时,还应使用项目的真实入口重新测量。

本地数据库

单个 CLI 安装需要保存结构化数据时,默认推荐 Node.js 内置的 node:sqlitefunc 要求 Node.js 24.15 或更高版本,因此无需额外安装数据库功能包、原生扩展或独立服务。同步的 DatabaseSync API 适合执行时间短的命令、本地索引、缓存、历史记录,以及使用 :memory: 的测试。

import { Injectable } from 'func'
import type { OnDispose } from 'func'
import { DatabaseSync } from 'node:sqlite'

type Project = Readonly<{ path: string }>

@Injectable()
export class DatabaseService implements OnDispose {
  private readonly database = new DatabaseSync('data.sqlite', {
    timeout: 5_000,
  })
  private readonly findProjectStatement = this.database.prepare(
    'SELECT path FROM projects WHERE name = ?',
  )

  findProject(name: string) {
    return this.findProjectStatement.get(name) as Project | undefined
  }

  onDispose() {
    this.database.close()
  }
}

在所属 Module 的 providers 中注册 DatabaseService,再通过构造函数注入需要它的 Command。func 只会在选中的 Command 需要时创建这个 service,并在本次调用结束后执行 onDispose()

来自用户的值应通过 prepared statement 绑定,并保持事务简短。多个本地进程可能访问同一数据库时,可以考虑启用 WAL,但不要把 WAL 数据库放在网络文件系统上。由于每个 DatabaseSync 操作都会阻塞当前 JavaScript 线程,长时间查询、高并发写入或跨主机共享数据应改用 Worker,或者外部数据库及其驱动。

文字颜色与样式

Node.js 内置的 util.styleText 无需安装依赖即可提供基础 ANSI 样式。需要统一 API、更丰富的颜色或更广的模块兼容性时,可以选择下面的第三方库。

功能包最近一周下载量适合场景代表性 Bundle 增量
picocolors≈218M需要常用颜色和强调样式的小型 ESM/CJS API;普通输出的默认第三方选择2 KiB
ansis≈44.5M同时需要 ESM/CJS、HEX/RGB、模板字符串和颜色自动降级4 KiB
chalk≈486M更看重成熟的链式 API、丰富颜色能力和广泛的生态认知8 KiB
kleur≈90.7M需要紧凑的链式 ESM/CJS API,或已有项目已经使用它2 KiB

新的 CLI 如果只需要常用颜色,可以从 picocolors 开始。既要高级颜色又要兼顾 ESM/CJS 时选择 ansis;更看重成熟 API 和现有集成时选择 chalk

Prompt、Spinner 与任务流

功能包最近一周下载量适合场景代表性 Bundle 增量
@clack/prompts≈18.0M希望 Prompt、日志和 Spinner 风格统一的项目创建器与配置向导17 KiB
@inquirer/prompts≈34.6M需要更多输入类型、模块化导入或自定义 Prompt28 KiB
listr2≈43.3M包含嵌套、并行、跳过或动态输出的多任务流程79 KiB
ora≈83.5M需要明确成功、警告和失败状态的单个或少量异步操作58 KiB

安装或配置向导可以优先使用 @clack/prompts;输入类型和扩展能力是主要要求时选择 @inquirer/promptsora 适合独立操作,多个任务需要同时保留并分别展示状态时,listr2 更合适。

表格、进度与重点信息

功能包最近一周下载量适合场景代表性 Bundle 增量
cli-table3≈32.1M需要 ANSI 感知的对齐、换行、跨行或跨列表格34 KiB
cli-progress≈10.1M任务具有可测量总量,需要单个或多个进度条24 KiB
boxen≈27.7M带边框的通知、摘要和少量需要突出显示的信息49 KiB
log-update≈43.9M需要原地刷新自定义多行输出的底层能力34 KiB

报告型输出通常选择 cli-table3,能够用数字表示完成度的任务更适合 cli-progressboxen 用于强调信息,不适合作为布局系统;现成 Spinner 或进度渲染器无法满足要求时,再使用 log-update 自行控制刷新。

完整终端界面

需要键盘导航、焦点管理、持续存在的多区域布局或全屏更新时,可以考虑 TUI 框架。只需要表格、Prompt 或单个 Spinner 时没有必要引入这一层。

功能包最近一周下载量适合场景代表性 Bundle 增量
ink≈5.7M希望使用组件、状态、Flexbox 风格布局和组件测试的 React 团队362 KiB
terminal-kit≈202K需要命令式键鼠、屏幕缓冲区、绘图和图片能力无可靠单文件结果
blessed≈1.4M维护已经基于类 DOM Widget API 构建的终端应用264 KiB

新的 React 终端应用可以优先考虑 Ink。Terminal Kit 提供了更广的底层终端能力,但动态资源会增加单文件发布的处理成本。Blessed 对已有应用仍有价值,新项目采用前应重点评估维护状态和兼容性。

知名项目选用

下面的项目展示了这些库在不同交互复杂度下的实际使用情况。它们可以作为实现参考,但知名项目的选择不等于对所有场景的推荐。

功能包采用项目资料
@clack/promptsVite 的 create-vite、OpenClaw、create-t3-app 和 OpenCodeVite 源码OpenClaw 依赖
inkClaude Code、Gemini CLI、GitHub Copilot CLI、Cloudflare Wrangler、Prisma、Shopify CLI 和 Canva CLIInk 官方项目展示

最小的调用级接入方式见交互式应用