Yuku
Introduction
Yuku is a high-performance JavaScript and TypeScript compiler toolchain written in Zig, usable from Zig and from JavaScript through npm.
Why Yuku
Correct. 100% ECMAScript spec compliant, with zero failures and zero AST mismatches across the test suite.
Fast. Data-oriented from the ground up, with rigorous performance engineering.
Small. A fraction of the install size of the alternatives, with one core shared by every package, see Size.
Zero dependencies. Pure Zig, easy to build, embed, and cross-compile.
Modern. Full support for modern and experimental syntax, including decorators, source phase and deferred imports, and using declarations.
About these docs
These pages cover the surface: what each part does and the API you build on. Beneath it is far more, a core built for exactness and speed down to the last detail. To go deeper, read the source. It is typed and documented throughout, and it answers you or your coding agent more precisely than any guide could. Each npm package documents its complete JavaScript API in its README.
JavaScript
| Package | For |
|---|---|
yuku-parser | Parsing to an ESTree / TypeScript-ESTree AST |
yuku-analyzer | Scopes, bindings, references, and module linking |
yuku-codegen | Printing an AST back to source, with source maps |
Each package documents its API in its README.
The core, Yuku’s compiled code, is shared by every package, so it downloads once however many you install. yuku-parser and yuku-analyzer together install 907 kB, against 1.58 MB with a binary each. Toolchains with a binary per tool repeat the parser in every one, so the gap widens with each tool Yuku adds. Future tools, such as the transformer, use the core’s parser instead of their own.
WebAssembly
The core comes in two builds with the same API and byte-identical results. The native core is the fastest and the default, installed for your platform with no setup.
The WebAssembly core runs anywhere: browsers, edge runtimes, and platforms without a native build. Install @yuku-core/wasm, load it once, and pass it to every package that takes one.
import { load } from "@yuku-core/wasm";
import { parse } from "yuku-parser";
const core = await load();
parse("const x = 1;", { core });
To choose the native core explicitly, load it from yuku-core the same way.
For runtimes that import .wasm files as compiled modules, such as Cloudflare Workers, use loadSync.
import { loadSync } from "@yuku-core/wasm";
import wasm from "@yuku-core/wasm/yuku-core.wasm";
import { parse } from "yuku-parser";
const core = loadSync(wasm);
parse("const x = 1;", { core });
Zig
zig fetch --save git+https://github.com/yuku-toolchain/yuku.git
// build.zig
const yuku = b.dependency("yuku", .{ .target = target, .optimize = optimize });
my_module.addImport("parser", yuku.module("parser"));
Yuku requires Zig 0.16.0 or later.
Performance
Measured against the alternatives doing the same work, on an Apple M3.
Parser
Parsing natively, Yuku is faster than Oxc and about 2× faster than SWC.
typescript.js (7.8 MB) natively · benchmark
On npm, Yuku parses 3–10× faster than the alternatives.
react.js (72 KB) on npm · benchmark
The lead holds on large files.
typescript.js (7.8 MB) on npm · benchmark
Analyzer
Analyzing a whole codebase, with every reference resolved and every import linked across files, Yuku is 5–11× faster than typescript-eslint, and 4–7× faster than TypeScript through its API.
The lead holds on a single large file.
typescript.js (7.8 MB) on npm · benchmark
Size
Installed with npm, dependencies included:
| To | Yuku | Others |
|---|---|---|
| Parse | yuku-parser 730 kB | oxc-parser 4.7 MB, @babel/parser 4.8 MB, @typescript-eslint/typescript-estree 26.3 MB |
| Analyze scopes and references | yuku-analyzer 860 kB | @typescript-eslint/typescript-estree + @typescript-eslint/scope-manager 26.7 MB |
| Print an AST | yuku-codegen 200 kB | astring 270 kB, @babel/generator 2.5 MB |