This repository is a fork of yuku-toolchain/ecmascript-parser-benchmark-native, maintained to update parser benchmark data and add parsers.
Benchmarks for ECMAScript parsers compiled to native binaries (Zig, Rust), measuring raw parsing speed without any JavaScript runtime overhead.
| Property | Value |
|---|---|
| OS | macOS 25.6.0 (arm64) |
| CPU | Apple M5 Max |
| Cores | 18 |
| Memory | 64 GB |
Language: Zig
A high-performance & spec-compliant JavaScript/TypeScript compiler toolchain written in Zig.
Language: Rust
A high-performance JavaScript and TypeScript parser written in Rust.
Language: Rust
An extensible Rust-based platform for compiling and bundling JavaScript and TypeScript.
Language: Rust
The next-generation SWC JavaScript and TypeScript parser.
File size: 7.83 MB
| Parser | Median | Min | p99 | Relative |
|---|---|---|---|---|
| SWC Next | 12.29 ms | 11.74 ms | 15.08 ms | 1.00× |
| Yuku | 13.84 ms | 13.57 ms | 15.83 ms | 1.13× |
| Oxc | 17.73 ms | 16.98 ms | 18.74 ms | 1.44× |
| SWC | 32.59 ms | 30.40 ms | 39.48 ms | 2.65× |
File size: 2.95 MB
| Parser | Median | Min | p99 | Relative |
|---|---|---|---|---|
| SWC Next | 4.50 ms | 4.17 ms | 5.65 ms | 1.00× |
| Yuku | 4.71 ms | 4.51 ms | 5.70 ms | 1.05× |
| Oxc | 5.67 ms | 5.33 ms | 8.19 ms | 1.26× |
| SWC | 10.82 ms | 9.75 ms | 13.27 ms | 2.40× |
File size: 2.24 MB
| Parser | Median | Min | p99 | Relative |
|---|---|---|---|---|
| SWC Next | 1.26 ms | 1.21 ms | 1.54 ms | 1.00× |
| Yuku | 1.60 ms | 1.56 ms | 1.70 ms | 1.27× |
| Oxc | 1.81 ms | 1.61 ms | 3.41 ms | 1.44× |
| SWC | 3.85 ms | 3.64 ms | 4.97 ms | 3.05× |
File size: 0.07 MB
| Parser | Median | Min | p99 | Relative |
|---|---|---|---|---|
| SWC Next | 0.06 ms | 0.06 ms | 0.12 ms | 1.00× |
| Yuku | 0.07 ms | 0.07 ms | 0.09 ms | 1.30× |
| Oxc | 0.09 ms | 0.08 ms | 0.16 ms | 1.48× |
| SWC | 0.21 ms | 0.20 ms | 0.34 ms | 3.68× |
The ECMAScript specification defines a set of early errors that conformant implementations must report before execution. Some of these are detectable during parsing from local context alone, like return outside a function, yield outside a generator, invalid destructuring, etc. Others require knowledge of the program's scope structure and bindings, such as redeclarations, unresolved exports, private fields used outside their class, etc.
Parsers handle this differently: SWC checks some scope-dependent errors during parsing itself, while Yuku, Oxc, and SWC Next provide a separate semantic analysis pass. This keeps parsing fast and lets each consumer opt in only to the work it actually needs. A formatter, for example, only needs the AST and should not pay the cost of scope resolution.
The benchmarks below measure parsing followed by this additional pass, which builds a scope tree and symbol table, resolves identifier references to their declarations, and reports the remaining early errors. SWC Next enables SyntaxChecks::all(); Yuku enables check = true. These timings do not establish equivalent conformance coverage.
| Parser | Median | Min | p99 | Relative |
|---|---|---|---|---|
| SWC Next + Semantic | 26.33 ms | 25.27 ms | 30.64 ms | 1.00× |
| Yuku + Semantic | 29.39 ms | 28.14 ms | 35.24 ms | 1.12× |
| Oxc + Semantic | 33.82 ms | 32.74 ms | 40.61 ms | 1.28× |
| Parser | Median | Min | p99 | Relative |
|---|---|---|---|---|
| SWC Next + Semantic | 10.07 ms | 9.74 ms | 15.47 ms | 1.00× |
| Yuku + Semantic | 10.63 ms | 10.11 ms | 11.14 ms | 1.06× |
| Oxc + Semantic | 11.59 ms | 11.09 ms | 13.63 ms | 1.15× |
| Parser | Median | Min | p99 | Relative |
|---|---|---|---|---|
| SWC Next + Semantic | 2.62 ms | 2.40 ms | 3.16 ms | 1.00× |
| Yuku + Semantic | 2.76 ms | 2.65 ms | 3.82 ms | 1.05× |
| Oxc + Semantic | 3.04 ms | 2.84 ms | 3.87 ms | 1.16× |
| Parser | Median | Min | p99 | Relative |
|---|---|---|---|---|
| SWC Next + Semantic | 0.12 ms | 0.12 ms | 0.21 ms | 1.00× |
| Yuku + Semantic | 0.16 ms | 0.15 ms | 0.28 ms | 1.29× |
| Oxc + Semantic | 0.18 ms | 0.17 ms | 0.29 ms | 1.48× |
- Node.js 22.18 or later - Script runtime
- pnpm - Package manager
- Rust - For building Rust-based parsers
- Zig 0.17.0 - Required by Yuku 0.27.0
- Clone the repository:
git clone https://github.com/yuku-toolchain/ecmascript-parser-benchmark-native.git
cd ecmascript-parser-benchmark-native- Install dependencies:
pnpm install
- Download the benchmark files:
pnpm run load-files
- Build the parsers:
pnpm run build
- Run benchmarks:
pnpm bench
This will run benchmarks on all test files. Results are saved to the result/ directory.
Parsing is timed in-process to isolate it from process startup, dynamic linking, file I/O, and memory teardown, which would otherwise dominate the measurement on smaller files.
The source is read once, then each parser runs 50 warmup iterations followed by 300 timed iterations. A monotonic clock wraps only the parse call (plus the semantic pass for the semantic variants); allocation and teardown happen outside the timed region, and the result passes through an optimization barrier so the work cannot be elided. Reported figures are the median, minimum, and 99th percentile of the timed runs.
Binaries are built with release optimizations: Rust with cargo build --release (LTO, single codegen unit, symbol stripping) and Zig with zig build --release=fast. Each uses a fast general-purpose allocator (Rust mimalloc, Zig smp_allocator).