Yuku
Testing
Correctness in Yuku is not an afterthought. A large share of the work behind the toolchain went into the test suite and the infrastructure around it, built and maintained with the same care as the parser itself. It covers everything from spec conformance and exact AST shapes to codegen soundness, source map accuracy, and memory behavior under simulated out-of-memory conditions. This page describes how it all works.
The parser test suite
The parser is validated against a dedicated repository, parser-test-suite, a comprehensive ECMAScript test suite targeting the ESTree and TypeScript-ESTree AST formats. Its tests come from three sources.
- tc39/test262, the official ECMAScript conformance suite, covering language grammar, built-ins, Annex B, Intl, and staging proposals.
- microsoft/TypeScript compiler test fixtures.
- babel fixtures for JSX.
The suite holds over 50,000 tests, and it grows as upstream grows. As a rough shape, JavaScript makes up the bulk with around 45,000 cases, TypeScript adds around 8,000, and JSX contributes a smaller set of focused cases.
Each language suite splits into three categories.
| Category | Expectation |
|---|---|
pass | Must parse cleanly, and the AST must exactly match a snapshot |
fail | Must produce a parse error |
semantic | Parses cleanly, but must be rejected by semantic analysis |
What a passing test verifies
A pass test is much stricter than “it parses”.
- Zero diagnostics. The file must parse without a single error.
- Exact AST match. The full parse result, the program, every node type, every field, every position, plus comments, is compared structurally against a snapshot, ESTree for JS/JSX and TypeScript-ESTree for TS.
- Walk order. Traversing the tree must visit children in source order, an invariant every ESTree walker relies on.
Pass files also run with semantic analysis enabled, so the early-error checker is simultaneously validated for zero false positives on valid code.
fail tests cover syntax the parser must reject. semantic tests cover the scope-dependent early errors that cannot be caught from local context alone, such as strict mode violations, duplicate lexical bindings, unresolved exports, and private fields used outside their class. These files parse fine, but must fail once semantic analysis runs.
Where the snapshots come from
The expected ASTs are not produced by Yuku. Snapshots are generated with an independent reference parser, Oxc, which emits ESTree output for JS/JSX and TypeScript-ESTree output for TS. This keeps Yuku from grading its own homework. Matching an independently generated AST proves Yuku produces the exact tree shape the ESTree ecosystem agrees on, not just output consistent with itself.
Synced with the spec, daily
Test262 and the TypeScript compiler are moving targets, with new proposals and features landing in them continuously. An automated job in the suite repository checks upstream every day and adds the new tests, and Yuku’s test runner refreshes its local copy of the suite daily. When a proposal reaches Test262, Yuku is tested against it almost immediately.
Conformance status
Yuku passes the entire suite, every pass, fail, and semantic test, with zero failures and zero AST mismatches. Per-file results are generated on every run and published in test/parser/results.
The suites run through the published npm packages, built from the local Zig source. So every run validates not just the Zig core but the whole chain, from the parser through the native bridge to the JavaScript API, with exact AST matching between Zig and JavaScript.
Codegen
Curated inline-snapshot tests pin the exact output of print, strip, and minify on inputs chosen by hand. On top of that, the corpus suite runs all three operations over every parseable file in the parser test suite and checks a set of invariants.
- Every operation’s output parses cleanly again.
printis semantics-preserving, meaning the reparsed AST equals the original, modulo positions.- Every operation is a fixed point on its own output, and no comment is lost or duplicated.
Source maps
Every corpus file is round-tripped through print with source maps enabled, and every identifier in the output must trace back to the right name and position in the original source.
Fuzzing
Beyond the fixed suites, a Zig-side fuzzer throws millions of randomized inputs per run at the parser, adversarial fragments (malformed surrogate escapes, unterminated literals, numeric and regex corner cases, raw invalid UTF-8 bytes) and mutations of structurally complete programs, across every language mode, with simulated out-of-memory conditions injected along the way. The parser must never crash, whatever the input. Any failure dumps a self-contained reproducer.
Memory
The parser is deliberate about memory. Everything a parse allocates, the nodes, spans, strings, and diagnostics, lives in a single arena owned by the tree, and tree.deinit() is a single free. There are no per-node allocations to leak and no ownership graph to get wrong. The fuzzer’s simulated allocation failures exercise exactly this pattern, so the expectation holds even when memory runs out. No crashes, no segfaults, no leaks. Yuku is memory safe and memory efficient by construction, and it is tested to stay that way.
Running the suites
bun run test
On first run this downloads the parser test suite (cached for a day), builds the native addons from your local Zig, then runs every suite. Each suite can also be run on its own, and you can add your own cases. See CONTRIBUTING.md for the details.