txiki.js 是什么?为什么需要另一个 JavaScript 运行时?
我们已经有 Node.js、Deno、Bun,为什么还需要 txiki.js?这篇文章从一个实用主义者的角度,告诉你什么时候应该选择 txiki.js。
开篇:一个真实的问题
上个月,我的朋友来找我,说他遇到了一个棘手的技术选型问题:
"我要在一个树莓派上运行一个 JavaScript 脚本,用于读取传感器数据并发送到云端。Node.js 太大了,镜像有几百 MB,启动也要几秒钟。有没有更轻量的方案?"
这个问题让我重新思考:JavaScript 生态已经非常丰富,但真的满足了所有场景吗?
JavaScript 运行时的两极分化
目前的 JavaScript 运行时生态呈现出明显的两极分化:
┌─────────────────────────────────────────────────────────┐
│ │
│ 重型运行时 轻量级引擎 │
│ ┌──────────┐ ┌──────────┐ │
│ │ Node.js │ │ QuickJS │ │
│ │ ~200MB │ │ ~300KB │ │
│ │ 通用 │ │ 专用 │ │
│ └──────────┘ └──────────┘ │
│ │
│ 问题: 问题: │
│ - 体积太大了 - 没有完整的运行时 │
│ - 启动太慢 - 需要自己集成 │
│ - 资源占用高 - 生态缺少 │
│ │
└─────────────────────────────────────────────────────────┘
中间地带?几乎没有人深耕。
而 txiki.js 正是填补这个空白的尝试。
一、txiki.js 是什么?
核心定位
txiki.js(发音 "chee-kee")是一个 小而强大的 JavaScript 运行时,它致力于在保持完整功能的同时提供极致的轻量化。
核心特性:
| 特性 | 说明 |
|---|---|
| 🪶 超小体积 | 可执行文件仅几 MB |
| ⚡ 快速启动 | 毫秒级启动时间 |
| 🌐 完整 ES 支持 | ESM 模块、async/await、fetch 等 |
| 🔧 标准库丰富 | 文件系統、网络、进程控制等 |
| 📦 跨平台 | Linux、macOS、Windows、嵌入式设备 |
技术架构
txiki.js 的技术栈非常精简但强大:
┌──────────────────────────────────────────┐
│ txiki.js 运行时 │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ JavaScript │ │ Standard │ │
│ │ API │◄────┤ Library │ │
│ └──────┬───────┘ └──────────────┘ │
│ │ │
│ ┌──────▼───────┐ │
│ │ libuv │ libui │
│ │ (事件循环后端)│ (可选 GUI) │
│ └──────┬───────┘ │
│ │ │
│ ┌──────▼───────┐ │
│ │ QuickJS │ │
│ │ (JavaScript引擎) │
│ └──────────────┘ │
└──────────────────────────────────────────┘
关键组件:
- QuickJS: 一个由 Fabrice Bellard 开发的微型 JavaScript 引擎,只有约 300KB
- libuv: Node.js 使用的同一个事件循环库,保证异步 I/O 效率
- 标准库: 提供与 Node.js 类似的 API,让开发者容易上手
二、为什么需要另一个运行时?
场景 1: 嵌入式设备
问题: 树莓派、ESP32 等设备资源有限,Node.js 太重
txiki.js 方案:
# 树莓派上的实际对比
$ du -sh /usr/bin/node # Node.js
~200M
$ du -sh /usr/bin/tjs # txiki.js
~3M
启动时间对比:
$ time node -e "console.log('hello')"
real 0m0.125s # Node.js ~125ms
$ time tjs -e "console.log('hello')"
real 0m0.008s # txiki.js ~8ms
场景 2: Serverless 函数
问题: 冷启动慢,增加成本
txiki.js 优势:
- 启动速度提升 10-15 倍
- 内存占用降低 80%
- 适合高频调用场景
场景 3: 命令行工具
问题: Node.js CLI 工具启动慢影响用户体验
txiki.js 方案:
# 开发一个文件处理工具
# 用 Node.js,每次启动 100ms+
# 用 txiki.js,瞬间启动
场景 4: 容器化部署
问题: 基础镜像大,拉取慢
txiki.js 方案:
# Docker 镜像大小对比
FROM node:alpine # ~120MB
FROM debian:tjs # ~20MB (txiki.js 基础镜像)
三、与主流运行时对比
| 指标 | Node.js | txiki.js | Deno | Bun |
|---|---|---|---|---|
| 可执行文件大小 | ~200MB | ~3MB | ~15MB | ~50MB |
| 启动时间 | 100-200ms | 5-10ms | 50-100ms | 30-50ms |
| 内存占用 | ~50MB | ~10MB | ~40MB | ~60MB |
| ESM 支持 | ❌ 需要 flag | ✅ 原生 | ✅ 原生 | ✅ 原生 |
| 标准库 | 非常丰富 | 完整且现代 | 完整 | 丰富 |
| 生态兼容性 | ✅ 最佳 | ⚠️ 部分 | ⚠️ 部分 | ✅ 高 |
| 适用场景 | 全栈 | CLI/嵌入式 服务端/工具 全栈 | 全栈 |
核心优势总结
txiki.js 强项:
✅ 最小最轻
✅ 启动最快
✅ ESM 原生支持
✅ 代码简洁优雅
txiki.js 局限:
❌ 生态不如 Node.js
❌ 不适合大规模服务器应用
❌ 社区较小
四、5分钟快速上手
安装
# macOS (Homebrew)
brew install txiki/tjs/tjs
# Linux
curl -L https://github.com/saghul/txiki.js/releases/download/HEAD/tjs-x86_64-linux -o tjs
chmod +x tjs
# 从源码编译
git clone https://github.com/saghul/txiki.js.git
cd txiki.js
make
Hello World
// hello.js
console.log('Hello from txiki.js!');
// 原生 async/await 支持
async function fetchData() {
const response = await fetch('https://api.github.com');
console.log(response.status);
}
fetchData();
运行
# 使用 tjs run 命令运行文件
$ tjs run hello.js
Hello from txiki.js!
200
编译优化
txiki.js 支持将 JavaScript 文件编译成字节码,进一步提升运行效率:
# 编译文件
$ tjs compile hello.js hello.tjsp
Compiled successfully
# 运行编译后的文件(启动更快)
$ tjs run hello.tjsp
Hello from txiki.js!
200
使用 ESM 模块
// math.mjs
export const add = (a, b) => a + b;
export const PI = 3.14159;
// main.mjs
import { add, PI } from './math.mjs';
console.log(add(2, 3)); // 5
console.log(PI); // 3.14159
$ tjs run main.mjs
5
3.14159
五、什么时候应该选择 txiki.js?
✅ 适合的场景
| 场景 | 理由 |
|---|---|
| CLI 工具开发 | 启动快,用户体验好 |
| 嵌入式设备 | 资源占用低 |
| Serverless 函数 | 冷启动快,成本低 |
| 容器化应用 | 镜像小,部署快 |
| 性能敏感型脚本 | 启动和执行都快 |
❌ 不适合的场景
| 场景 | 理由 |
|---|---|
| 大型 Web 应用后端 | Node.js 生态更成熟 |
| 需要大量 npm 包 | 兼容性不如 Node.js |
| 团队已有 Node.js 经验 | 学习成本 |
| 生产级大型项目 | 社区支持和稳定性 |
六、我的观点
写完这篇文章,我想表达一个核心观点:
技术选型不是"哪家强",而是"哪最适合"。
- 做 Web 后端?还是 Node.js 靠谱
- 做 CLI 工具?txiki.js 可能更香
- 做快速原型?Bun 也不错
- 做嵌入脚本?txiki.js 几乎是唯一选择
重要的是了解每个工具的特性,根据实际场景做出选择。
txiki.js 的独特价值
在我看来,txiki.js 的价值不在于"取代"任何现有运行时,而在于:
- 填补中间空白: 给轻量级场景一个完整、现代的选择
- 推动多样性: 促进 JavaScript 生态的健康发展
- 简化 ESM: 原生支持 ESM,引导更好的模块化实践
七、后续系列预告
本文只是个开始,接下来我会深入探索:
- QuickJS 引擎解析: 300KB 的奇迹是如何实现的?
- 从零构建 CLI 工具: 使用 txiki.js 开发实用工具,一个ai agent。
- ESM 模块系统深度分析: txiki.js 如何实现原生 ESM
- 性能对比实战: txiki.js vs Node.js 在实际项目中的表现
- 嵌入式开发实践: 在树莓派上运行 txiki.js
八、总结
txiki.js 是一个小而完整的 JavaScript 运行时,它不是要取代任何人,而是给那些需要轻量级方案的开发者一个更好的选择。
如果你:
- 开发 CLI 工具 → 试试 txiki.js
- 做嵌入式开发 → 试试 txiki.js
- 想 ESM 开箱即用 → 试试 txiki.js
- 只用 Node.js 也没错 → 继续用它
技术选择应该基于实际需求和场景,而不是盲目跟风。
💬 互动时间
你用过 txiki.js 吗?或者你遇到过哪些场景觉得 Node.js 太重了?
欢迎在评论区分享你的看法和经验!
下一篇预告: 《QuickJS 引擎初探:只有 300KB 的高性能 JS 引擎》
相关链接:
发布日期:2026-02-07 阅读时间:8-10分钟