What Is pipa?
pipa is an open-source ES2023 JavaScript runtime built in Rust by the restsend project, aimed at engineers who need an embeddable script engine instead of a full browser or Node stack. pipa is one of the best Embedded JavaScript Runtimes tools for Rust developers and backend teams. As of the 2026-05-24 benchmark run in the repo, it scored 1254 in the V8 suite versus QuickJS at 1208, while the binary stays around 5.2 MB with the repl feature enabled.
Quick Overview
| Attribute | Details |
|---|---|
| Type | Embedded JavaScript Runtimes |
| Best For | Rust developers and backend teams embedding JavaScript |
| Language/Stack | Rust, ES2023, register-based bytecode, async/await, fetch/WebSocket/SSE |
| License | MIT |
| GitHub Stars | N/A in the provided page text |
| Pricing | Open-Source |
| Last Release | 0.1.2 — date not listed on the provided page text |
| Benchmark Snapshot | 1254 V8 score vs 1208 for QuickJS, measured 2026-05-24 |
| test262 Snapshot | ~52% sampled pass rate excluding intl402 and annexB, measured 2026-05-24 |
Who Should Use pipa?
- Rust library authors embedding scripting into a server, CLI, or desktop app who want a native Rust runtime instead of a foreign VM boundary.
- Backend engineers who need user-defined automation, templating, or policy logic without shipping a full Node.js process.
- Indie hackers building a product with scriptable extensions and wanting bytecode files (
.jsc) for faster cold starts. - Platform teams that need a small runtime with built-in
fetch, WebSocket, and SSE primitives for controlled internal workloads.
Not ideal for:
- Apps that rely on the full JavaScript ecosystem, npm packages, or Node-specific APIs.
- Workloads that need complete compatibility with
Proxy,Reflect,Intl, or Annex B semantics. - Teams that need near-perfect
test262coverage before allowing untrusted or third-party scripts.
Key Features of pipa
- ES2023 compliance — pipa tracks the ECMAScript 2023 spec, so you get modern language features like
async/await, classes, destructuring, and the current core syntax surface without transpilation. - Bytecode compilation — you can compile JavaScript to
.jscfiles and choose optimization levels from-O0through-O3. That is useful when you want faster startup, repeatable deploy artifacts, or offline execution. - Built-in async runtime —
async/awaitworks natively, and the embedding API exposeseval_asyncfor event-loop driven execution. That makes pipa fit request/response flows and background task orchestration better than synchronous-only embedders. - Zero-dependency networking primitives —
fetch, WebSocket, and Server-Sent Events are implemented in Rust without external C libraries for the core feature set. The repo notes thatfetchrequiresrusttls, but the design still avoids dragging in a large system dependency chain. - Compact binary size — the shipped binary is about 5.2 MB with
replenabled, which is small enough for shipping inside a container image or a single static deployment artifact. Small size matters when you need fast pulls and low disk overhead. - Rust embedding API — the runtime exposes
JSRuntime,JSContext, and helpers likeeval,eval_async, andcompile_to_register_bytecode. That gives Rust code direct control over value conversion, builtin registration, and custom host functions. - Measured benchmark lead over QuickJS — the repo’s 2026-05-24 V8 suite shows pipa with a total score of 1254, ahead of QuickJS at 1208. The gain is not universal across all microbenchmarks, but the aggregate result shows the VM is competitive where it matters.
pipa vs Alternatives
| Tool | Best For | Key Differentiator | Pricing |
|---|---|---|---|
| pipa | Embedded scripting inside Rust apps | ES2023 runtime in Rust with bytecode and built-in async I/O | Open-Source |
| QuickJS | Minimal embeddable JS with broad adoption | Mature, tiny C runtime with a very small footprint | Open-Source |
| Node.js | Full server-side JavaScript and npm ecosystem | Huge package ecosystem and battle-tested production tooling | Open-Source |
| Boa | Pure-Rust JavaScript experimentation | Rust-native VM with a strong standards focus | Open-Source |
Pick QuickJS when you need a proven embedded engine and can accept its C-based implementation and narrower built-in networking story. Pick Node.js when package ecosystem depth matters more than embedding simplicity or binary size.
Pick Boa when you want a Rust-native JavaScript engine and can tolerate a more experimental feature set. If you are building local command-line automation around script execution, browse all CLI tools; if you need to trace script-driven service behavior, pair pipa with OpenTrace.
How pipa Works
pipa uses a Rust VM that parses ES2023 source, lowers it into internal bytecode, and executes that bytecode inside a managed JSRuntime and JSContext. The design choice is straightforward: keep the engine self-contained in Rust, avoid external C dependencies for core runtime features, and make startup deterministic by supporting precompiled .jsc artifacts.
The bytecode path is the most practical part of the architecture. You can run source directly, compile it to register-based bytecode, or disassemble bytecode for inspection when a script misbehaves, which is useful for debugging host integration and deployment drift.
cargo install pipa-js
pipa script.js
pipa -compile input.js output.jsc
pipa -diss output.jsc
pipa -O3 script.js
The commands above install the CLI, run a source file, emit bytecode, inspect the compiled output, and execute with higher optimization. In practice, you use source mode during development and .jsc files in production or distribution when startup latency and reproducibility matter.
Pros and Cons of pipa
Pros:
- Rust-native implementation reduces FFI friction when embedding JavaScript into a Rust service or tool.
- Bytecode support gives you a deployment format that is faster to load than raw source in repeat-run scenarios.
- Built-in async APIs cover common in-process automation use cases without forcing a separate Node process.
- Small binary footprint is practical for containers, desktop apps, and distributed CLIs.
- No external C runtime for core built-ins lowers portability risk and simplifies cross-compilation.
- Competitive benchmark result shows it can hold its own against QuickJS in aggregate V8-style testing.
Cons:
- Incomplete compatibility is visible in the repo’s sampled test262 results, which are around 52% overall as of 2026-05-24.
- Partial standard library coverage means
Promise,Proxy,Reflect, and collection types are not fully implemented. - Ecosystem isolation means you do not get npm, Node addons, or the usual server-side JavaScript package surface.
- Feature flags matter because
repl,fetch, andprocesssupport change the build shape and behavior. - Networking has a TLS dependency for
fetch, so the zero-dependency story is not absolute for every network path.
Getting Started with pipa
The fastest way to try pipa is to install the CLI and run either a source file or a precompiled bytecode file. If you are embedding it in Rust, add the crate dependency and disable default features when you do not need the REPL or process helpers.
cargo install pipa-js
pipa hello.js
pipa -compile hello.js hello.jsc
pipa hello.jsc
cargo build --release --no-default-features
After the install, pipa hello.js executes JavaScript directly and pipa -compile emits reusable bytecode. If you are using pipa as a library, start with default-features = false and enable only the features you actually need, because that keeps the final binary smaller and the dependency graph cleaner.
Verdict
pipa is the strongest option for embedding a small ES2023 engine into Rust when you care about startup time, bytecode deployment, and a self-contained runtime more than perfect JavaScript compatibility. Its biggest strength is the Rust-native architecture; its main caveat is incomplete test262 coverage and missing high-level JS primitives. Choose pipa for controlled scripting, not browser-grade parity.



