scriptc可将TypeScript编译为原生程序
Vercel Labs 近期发布了实验性 TypeScript 编译器 scriptc,采用 Apache 2.0 许可证。它的目标是把普通 TypeScript 程序转换成体积较小的原生可执行文件,生成物不内置 Node、V8 或其他 JavaScript 引擎。目前该仓库创建于 2026 年 7 月 22 日,已获得约 4900 个 Star。
scriptc 会调用真正的 TypeScript 编译器完成解析和类型检查,再把程序转换成带类型信息的中间表示,随后可输出可读 C 代码、LLVM IR、汇编、目标文件、原生可执行文件,也能通过 WASI Preview 1 生成 WebAssembly。它对语法结构采用三类处理:默认走静态编译;遇到 npm 包或 any 类型代码时,若启用 --dynamic,则交给约 620KB 的内嵌 quickjs-ng 动态执行;否则会在编译阶段拒绝,并给出 SC 错误码和修改建议。
在一组将 scriptc 0.0.16 与 Bun 1.3.12、Node 24.18.0 对比的测试中,scriptc 命令行启动时间中位数为 1.78 毫秒,Bun 为 21.29 毫秒,Node 为 61.78 毫秒。一个未使用框架的 node:http 服务器空闲内存仅 1.9MiB。不过,Hono 因需要开启 --dynamic,导致服务器中 62% 的代码落入 QuickJS 动态执行,吞吐量降至每秒 1.84 万次请求,而 Bun 可达到每秒 7.05 万次。
在开发者社区中,有测试者称 scriptc 在理想的字节数组场景下仍比 Node 24 慢约 7.5 倍,即便已经借助 Claude 做过针对性优化。但它的启动更快,约 1.5 毫秒对 18.6 毫秒;内存占用更低,约 2.5MiB 对 181MiB;最终还可得到一个无运行时依赖、约 370KB 的单文件可执行程序。
围绕性能路线也出现了不少争议。Filip Pizlo 认为,scriptc 将所有数字都表示为浮点数,并推迟整数类型推断,相当于回避了提升 JavaScript 性能的重要部分。他还指出,若项目以高性能为目标,依赖 QuickJS 并不理想,因为 any 在实际 TypeScript 项目中很常见,代码很容易不断进入动态执行区域。Simon Willison 则注意到,编码智能体在一周内提交了 91.8 万行代码,并认为无需写 C 或 Rust 就能生成小型快速二进制文件,仍然是一项有价值的能力。
兼容性同样是主要质疑点。有开发者把本地项目逐一进行覆盖检查后发现,每个项目都会产生数百个错误,因此认为它目前难以用于现有工程;如果只能从零开始、避免第三方库,再编译成二进制,那么 Rust、Go、Zig、C++、Nim、Swift、Kotlin Native 等原生编译语言可能更合适。也有人担心项目长期维护能力,并提到 Vercel 过去的 zerolang 在发布数周后便停止提交。Remo Jansen 曾尝试编译 TypeScript 6 编译器本身,但因内部错误失败;他的测试中,scriptc 冷启动为 3.6 毫秒,Node 为 48.9 毫秒,但计算任务耗时达到 2.33 秒,明显更慢。
使用 scriptc 需要 Node.js 24 或更高版本,可通过 npm install -g scriptc 安装。项目文档列出了一些有意设计的行为差异,例如字符串以 UTF-8 存储,内存管理使用引用计数而非垃圾回收,Object.keys 按声明顺序返回键,process.argv[0] 的值固定为 "scriptc"。其 npm 依赖指南还提供实验性 --npm-static 参数,可尝试把指定软件包移出动态执行区域并进行静态编译。
该编译器目前支持 macOS、Linux、Windows 与 WASI Preview 1。项目通过差分测试验证行为一致性,即逐字节比较它与 Node 的标准输出、标准错误和退出码。整体来看,scriptc 展示了 TypeScript 生成原生二进制的可能性,但官方仍明确将其标记为实验性项目,现阶段更适合探索和评估,而非直接承担成熟生产负载。
本文基于公开渠道信息整理,内容可能存在不准确或遗漏之处,不代表本站立场,如内容涉及侵权或错误,请联系我们处理。
阅读原文