pipa (枇杷) - A fast, minimal ES2023 JavaScript runtime built in Rust.
Features
- ES2023 compliant — implements the ECMAScript 2023 specification
- Async/await built-in — first-class async/await support without transpilation
- Bytecode support — compile JavaScript to
.jscbytecode files for fast loading and execution, with configurable optimization levels (-O0through-O3) - Fast — outperforms QuickJS in benchmarks
- Small — ~5.2 MB binary (with
replfeature) - Zero-dependency built-in implementations for:
- Regex/JSON/Base64/BigInt
- Unicode
fetch(HTTP client),rusttlsrequired- WebSocket
- Server-Sent Events (SSE)
No external C libraries or system dependencies for the above — everything is implemented from scratch in Rust.
Benchmarks (2026-06-15)
V8 benchmark suite comparison (higher is better):
| Benchmark | qjs | node | boa | pipa | vs qjs |
|---|---|---|---|---|---|
| Richards | 881 | 44629 | 133 | 866 | -1.7% |
| DeltaBlue | 875 | 88373 | 136 | 828 | -5.4% |
| Crypto | 1013 | 56374 | 118 | 985 | -2.8% |
| RayTrace | 1268 | 70299 | 276 | 589 | -53.5% |
| EarleyBoyer | 1831 | 84585 | 341 | 1225 | -33.1% |
| RegExp | 306 | 12316 | 58.1 | 841 | +174.8% |
| Splay | 2206 | 44299 | 459 | 2000 | -9.3% |
| NavierStokes | 1759 | 54166 | 257 | 2087 | +18.6% |
| SCORE (total) | 1101 | 50001 | 185 | 1075 | -2.4% |
Ranking: #1 node (50001) · #2 qjs (1101) · #3 pipa (1075) · #4 boa (185)
test262 Compatibility (2026-06-15)
Tested against tc39/test262 (excluding intl402).
| Category | Tests | Pass Rate | Notes |
|---|---|---|---|
| Core Builtins | |||
| Math | 324 | 100% (314/314, 10 skipped) | sumPrecise proposal skipped |
| Boolean | 50 | 100% (50/50) | |
| parseFloat | 54 | 100% (54/54) | VM exception handler fix |
| parseInt | 55 | 100% (55/55) | VM exception handler fix |
| Number | 339 | 100% (339/339) | VM exception handler fix |
| Object.is | 21 | 100% (21/21) | |
| Object.defineProperty | 1131 | 100% (1128/1128, 3 skipped) | |
| Object.create | 320 | 100% (320/320) | |
| Object.getPrototypeOf | 39 | 100% (39/39) | |
| Date | 594 | 93.6% (556/594) | |
| URI encode/decode | 173 | 89.6% (155/173) | URIError, UTF-8 validation, reserved chars, ToString coercion |
| Function | 507 | 85.2% (432/507) | |
| Other Builtins | |||
| Symbol | 98 | 93.9% (92/98) | auto-boxing strict, ToString call order, new Symbol() TypeError |
| JSON | 165 | 60.6% (100/165) | Reviver, toJSON, replacer, space, wrappers |
| Error | 180 | 52.8% (95/180) | |
| RegExp | 1878 | 42.3% (794/1878) | |
| String | 1222 | 77.2% (943/1222) | |
| Reflect | 153 | 68.6% (105/153) | Added get/set/has/deleteProperty/defineProperty/getOwnPropertyDescriptor/getPrototypeOf/setPrototypeOf/isExtensible/preventExtensions/ownKeys |
| Map | 203 | 22.2% (45/203) | |
| Set | 382 | 18.8% (72/382) | |
| BigInt | 77 | 44.2% (34/77) | Added ToIndex, RangeError/TypeError, ToBigInt coercion, property descriptors |
| Promise | 676 | 5.6% (38/676) | Limited async support |
| Proxy | 311 | 0% (0/311) | Not yet implemented |
Usage
# Run a script
# Run precompiled bytecode
# Compile JavaScript to bytecode
# Disassemble bytecode (debugging)
# Specify optimization level (default: -O2)
# Start REPL (requires the repl feature)
Embedding in Rust
Use pipa-js as a library to embed JavaScript in your Rust project:
[]
= "0.1.2"
Evaluate JavaScript
use ;
let mut rt = new;
let mut ctx = rt.new_context;
let val = eval.unwrap;
assert_eq!;
Read strings & values from JavaScript
use ;
let mut rt = new;
let mut ctx = rt.new_context;
eval.unwrap;
let val = eval.unwrap;
assert!;
let s = ctx.get_atom_str;
assert_eq!;
Call custom Rust functions from JavaScript
use ;
let mut rt = new;
let mut ctx = rt.new_context;
ctx.register_global_builtin;
eval.unwrap;
Async/await with event loop
use ;
let mut rt = new;
let mut ctx = rt.new_context;
eval_async.unwrap;
let val = eval.unwrap;
println!;
Requires the
fetchfeature (enabled by default).eval_asynciseval+run_event_loopin one call.
Bytecode compilation
use ;
let mut rt = new;
let mut ctx = rt.new_context;
// Compile JavaScript to register-based bytecode
let = compile_to_register_bytecode.unwrap;
// code: Vec<u8>, constants: Vec<JSValue>
assert!;
Build
# Default build (includes REPL, fetch, and process support)
# Minimal build (no REPL, no fetch, no process)
If using pipa as a library dependency and you don't need REPL/fetch/process features, add it with
default-features = false:[] = { = "0.1.1", = false }
License
MIT