
GitHub: https://github.com/swc-project/swc
swc 是用 Rust 重写 JavaScript/TypeScript 编译器的「前端工具链 LLVM」——单核作者 9 年、11,919 commits、33,615★,以 20× Babel 的速度被 Vercel/Next.js/Parcel/Deno 钦定为默认编译器,并通过 WASM 插件系统 + 零拷贝序列化把「速度」与「可扩展性」这两个对立面统一起来。
.ts/.tsx 编译默认走 swc 而不是 Babel,Vite、Parcel、Deno、Rspack 等十数个工具链直接消费 swc 9 年沉淀的 crate 拆分。Id<T> generational handle——三件套是任何写编译器/解析器/插件系统的项目都该照搬的设计。
— 类型: hero(官网头图,Speedy Web Compiler 标识)
Online Playground — 类型: demo(官方在线 Playground,可即时输入 TS 看转译输出)
筛选说明:总共发现 11 个媒体元素,筛选后保留 4 个;排除了 ~5 个 npm 下载量徽章、CI 状态、crates.io 版本等纯装饰元素。
https://github.com/swc-project/swcDonny/강동윤(kdy1),韩国开发者,2017-12 在 NAVER 体系下启动 swc,定位为「spdy web compiler」。9.2 年下来仍是单一 owner 主导(43% commits),合作者 OJ Kwon 与 Vercel/Next.js 团队形成「原作者 + 核心维护者 + 商业赞助方」三件套。值得注意的是:项目 Cargo.toml 的 authors 字段仍署名个人邮箱「강동윤 kdy1997.dev@gmail.com」——没有把版权转给 Vercel 也没有公司化,这是「个人 OSS + 公司背书」混合治理的现实样本。
Babel 时代 JS 工具链的核心矛盾:慢(JS 写)+ 灵活(plugin 集市)。Donny 看到的机会窗口是 Rust 在 2017-2018 编译器生态的成熟(rustc、deno 都已证明 Rust 能写工业级编译器),加上 Next.js 8+ Webpack 构建时间爆炸成为业界痛点——这是「速度优先 + WASM 插件保扩展」的时机判断。
AGENTS.md 写明:「Write performant code. Always prefer performance over other things.」——这不是口号而是 commit 评审条款。具体到执行层:
swc_core facade 单一 feature 矩阵选 crate,避免「latest of each crates will work」承诺被破。swc 在作者更大图景中的位置是 「上游公共品」——不是直接面向终端用户的工具,而是被 Next.js/Vite/Parcel/Deno 等十数个工具链消费的中间层。这种定位带来三条商业化路径:
官网设计哲学补充:「extensible」——WASM 插件系统 + rkyv 零拷贝序列化 = 把「JS 写 plugin + 原生级速度」两个以前对立的事统一了。
按新颖度×实用性排序:
Id<T> generational handle(新颖 4 / 实用 5 / 可迁移 5)——把 Rust 借用检查器在「pass 之间共享子节点」场景的痛点彻底解决。.github/workflows/{bench,binary-size,ecosystem-ci,claude}.yml 把「性能回归 + 二进制体积 + 生态集成」全自动化。模式 | 简述 | 适用场景 |
|---|---|---|
Atom = inline string + CoW | 32 字节内联 + 堆分配 fallback,避免 String 分配 | 任何 AST-heavy 库(Tree-sitter、oxc、Biome) |
rkyv 跨 FFI 边界 | 编译期 bytecheck + 共享内存传递 AST | plugin-heavy 系统(编辑器、规则引擎、AI agent runtime) |
scoped allocator + Id | 一次性 arena 分配 + 带 generation 的 typed handle | 编译器、查询引擎、游戏 ECS、规则引擎 |
Visit/Fold trait + Repeated | 自动重复 pass 直到 fixed point | 多 pass 优化、求解器 |
facade crate + feature flag | swc_core 统一 re-export + 互斥约束 | 多后端 + 多场景的基础库(数据库驱动、AI 推理、跨平台 GUI) |
明确「不做」清单 | #571 TS type checker 8 年争论后明确拒绝 | 任何「自己只做语法、不做语义」的工具 |
swc_core 单 facade crate,13 个 feature 在 lib.rs 顶层做 re-export + 互斥约束 - Trade-off: 用户爽了,crate 内部出现「feature 矩阵爆炸」「不显式 feature 即编译失败的玄学」 - 可迁移性: 极高——任何要发「多后端 + 多场景」的基础库都该照搬
#[repr(transparent)] struct Atom(hstr::Atom) 配合 Wtf8Atom 解决 UTF-16 surrogate;序列化端用 cbor4ii 自定义编解码 - Trade-off: unsafe 量增加(transmute / from_bytes_unchecked),需要 cbor 端 unsafe 配套 - 可迁移性: 极高——任何 AST-heavy 库都该走 inline-string + CoW
serde_json 跨边界要 marshal → 插件性能死结 - 方案: rkyv 0.8.16 + rancor 错误体系 + bytecheck 在编译期生成 CheckBytes;memory_interop.rs + runtime.rs 在 swc_plugin_runner 里做 guest→host 共享内存传递 - Trade-off: rkyv 0.8 还在快速演进,跨大版本 ABI 不稳;用户必须启用 feature 才能享受 - 可迁移性: 高——任何「host/guest 跨语言共享复杂数据结构」的场景都能用
clone() 是性能死结;用 Rust 生命周期又会和「pass 之间共享子节点」冲突 - 方案: crates/swc_allocator 提供 Allocator::scope(fn) 一次性 arena 分配;crates/swc_arena 用 Id<T> = NonZeroU64 + PhantomData 给不带生命周期的 typed handle,配 generation 防止悬垂引用 - Trade-off: scope 边界外的对象不能持有 arena 内指针(程序员心智负担),debug 难 - 可迁移性: 极高——编译器、查询引擎、游戏 ECS 都能直接套
swc_ts_fast_strip 与 binding_typescript_wasm 只做「类型注解剥除 + 枚举/命名空间降级」——把类型完全交给外部 tsc - Trade-off: 用户必须双跑(tsc --noEmit && swc);但与 tsc 行为一致,零边界 bug - 可迁移性: 极高——任何「自己只做语法、不做语义」的工具都该这样明确边界
swc_common + swc_atoms + swc_visit - 问题: 5 种语言管道如果各做各的 span/hygiene/error reporter 就会重复 5 次 - 方案: swc_common(span/hygiene/SourceMap/SyntaxContext/Mark)、swc_atoms(Atom/Wtf8Atom)、swc_visit(Visit/Fold trait + Repeated)下沉到所有语言管道共享 - Trade-off: swc_common 改动一次就影响 5 个语言管道,CI 矩阵必须五向都跑 - 可迁移性: 中——需要业务真的「多语言同源」才有价值
维度 | swc | oxc | biome | esbuild | babel |
|---|---|---|---|---|---|
语言 | Rust 97% | Rust | Rust + 部分 Go | Go | JS |
性能 vs Babel | 20× | 20×+ | 10-15× | 15-20× | 1× |
Plugin 系统 | WASM 插件 + rkyv 零拷贝 | 无(自建 transform API) | Rome 风格 config | 不可扩展(明确拒绝) | JS plugin 集市 |
AST | 自建(swc_ecma_ast) | 自建(oxc_ast) | 自建(biome_js_syntax) | 自建 | estree 兼容 |
多语言管道 | ES/CSS/HTML/XML/Regexp | ES(主)/ CSS | JS/TS + JSON | ES + CSS(部分) | JS/TS |
集成规模 | Next.js/Parcel/Deno 默认 | Vite 官方合作 | Rspack/Vite 部分 | Vite/Bun 默认 | 几乎所有 |
Conformance | test262 + tsc-references | test262 | test262 | test262 | test262 |
商业赞助 | Vercel/ByteDance/Shopify | ByteDance/Vite | 社区赞助 | 个人 + Cloudflare | 社区 + OpenJSF |
治理 | 单核 owner + 公司背书 | 较年轻单一团队 | 社区主导 | Evan Czaplicki 一人 | 基金会 + 社区 |
swc_ecma_compat_* / swc_ecma_regexp_* / swc_ecma_preset_env——「一个语言版本一个 crate」的细粒度拆分,竞品都在追赶。swc 已经从「Babel 的更快替代品」演化为「前端工具链的 LLVM 中间层」——不直接面向终端用户,而是被 Next.js/Vite/Parcel/Deno/Nuxt/Rspack 等十数个工具消费。
真正的胜负手是:当 plugin 生态足够大时,swc 不需要自己赢任何单点工具战——只要继续做「被集成最快的那块拼图」。
swc_core/src/ 的 __diagnostics.rs plugin.rs quote.rs 推断——新人 onboarding 成本高。swc 配置(默认就是),20× 速度提升立竿见影tsc --noEmit && swc(不要期待 swc 做类型检查)crates/swc_atoms/src/lib.rs——Atom 内联字符串是 swc 最值钱的「一行决策」crates/swc_plugin_runner/src/{runtime.rs, transform_executor.rs, memory_interop.rs}——WASM 插件执行核心crates/swc_allocator/src/lib.rs + crates/swc_arena/src/lib.rs——scoped allocator + Id 模式crates/swc_ecma_visit/src/lib.rs——Visit/Fold trait + Repeated 自动重复 passcrates/swc_core/Cargo.toml——facade crate 的 feature 矩阵设计
https://deepwiki.com/swc-project/swc(已收录,含 5 层 crate 架构详解)