binaryen.js: Binaryen's WebAssembly Compiler Infrastructure in JavaScript
A buildbot for browser & Node.js builds of Binaryen, a compiler infrastructure and toolchain library for WebAssembly.
At a glance
- What is it?
- binaryen.js is a buildbot that compiles the Binaryen C++ WebAssembly toolchain to JavaScript using Emscripten, making it available as an npm package named `binaryen`. It lets Node.js and browser code construct, validate, optimize, and emit WebAssembly modules without a native binary, and ships the Binaryen command-line tools as Node.js executables.
- Who is it for?
- binaryen.js is the right dependency when your Node.js or browser tool needs to generate or optimize WebAssembly programmatically: compile a custom language, run `wasm-opt` passes without a native binary, or inspect a `.wasm` file in a portable way. It is not the right choice if you simply want to run WebAssembly code in Node.js or the browser, since the runtime is built into both environments.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 12 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What binaryen.js Is and What Problem It Solves
Binaryen is a C++ compiler infrastructure library for WebAssembly. It provides a module representation, optimization passes, validation, and a suite of command-line tools. The upstream project at github.com/WebAssembly/binaryen is the reference implementation, written for native compilation.
binaryen.js is a separate repository that runs a buildbot to compile that C++ library to JavaScript using Emscripten, then publishes the result as an npm package named `binaryen`. The result lets JavaScript code running in Node.js or a browser use Binaryen's capabilities without a native binary: you can build a WebAssembly module by calling a JavaScript API, run optimization passes on it, validate it, and emit a `.wasm` binary, all from within a JavaScript process.
The primary users are tool authors: compilers targeting WebAssembly, AssemblyScript (which uses this package directly), `wasm-opt` wrappers in build pipelines, and other tooling that needs to reason about WebAssembly at the module level.
Installing and Running the First Example
Installation follows the standard npm workflow:
npm install binaryenThe README provides a complete example that constructs a module with an add function, optimizes it, and validates it:
import binaryen from "binaryen";
var myModule = new binaryen.Module();
myModule.addFunction("add", binaryen.createType([ binaryen.i32, binaryen.i32 ]), binaryen.i32, [ binaryen.i32 ],
myModule.block(null, [
myModule.local.set(2,
myModule.i32.add(
myModule.local.get(0, binaryen.i32),
myModule.local.get(1, binaryen.i32)
)
),
myModule.return(
myModule.local.get(2, binaryen.i32)
)
])
);
myModule.addFunctionExport("add", "add");
myModule.optimize();The package is an ES module (`"type": "module"` in `package.json`). The current published version is 132.0.0, matching the upstream Binaryen version.
Nightly Builds and CDN Delivery
The buildbot publishes nightly versions once a day when the upstream Binaryen repository has new changes. To install the latest nightly:
npm install binaryen@nightlyFor browser use without npm, the README documents three CDN paths. Two use jsDelivr: one sourcing from the GitHub repository directly and one from the npm package. The third uses unpkg:
https://cdn.jsdelivr.net/npm/binaryen@VERSION/index.jsThe README recommends pinning a specific version in production rather than using the unversioned latest URL. Previous published versions are available as GitHub tags.
The API Surface: Modules, Expressions, and Passes
The JavaScript API mirrors the Binaryen C API. The main entry point is `new binaryen.Module()`, which creates an empty module. From there, functions are added with `addFunction`, exports with `addFunctionExport`, and expressions are constructed using typed builders on the module: `myModule.i32.add`, `myModule.local.get`, `myModule.block`, and so on.
The type system maps directly to WebAssembly: `binaryen.i32`, `binaryen.i64`, `binaryen.f32`, `binaryen.f64`, `binaryen.v128`, and several reference types. `createType` builds a multi-value type from an array of types; `expandType` reverses it.
Module-level operations include `optimize` (run default optimization passes), `validate` (check well-formedness), `emitBinary` (produce a `Uint8Array` with the `.wasm` binary), `emitText` (produce Binaryen's s-expression text format), and `parseText` (parse that format back to a module). The `readBinary` static function creates a module from an existing `.wasm` file.
The API reference in the README covers control flow, variable access, integer and floating-point operations, memory access, bulk memory, SIMD vectors, atomic operations, exception handling, and reference types. Future-feature operations are marked with a unicorn emoji in the README and may not be supported by all runtimes.
Command-Line Tools in the npm Package
The npm package ships Node.js executables for all of Binaryen's command-line tools: `wasm-shell`, `wasm-opt`, `wasm-metadce`, `wasm2js`, `wasm-as`, `wasm-dis`, `wasm-ctor-eval`, `wasm-reduce`, and `wasm-merge`. These are listed in the `bin` section of `package.json` and are available in your PATH after installation.
This makes binaryen.js useful as a build dependency in projects that want to run `wasm-opt` passes during a Node.js build step without requiring a system-level Binaryen installation or a native binary in the repository. The tools run under the Emscripten-compiled JavaScript runtime, which makes them slower than the native binaries but eliminates the platform-specific binary distribution problem.
Relooper, Source Maps, and the Debugging API
Beyond module construction and optimization, the API includes three less commonly used but important features.
The Relooper converts control-flow graphs back into structured code. The API constructs a `Relooper` object, adds blocks and branches to it, renders the result, and disposes of it. This is used by compilers that work at the basic-block level internally and need to produce valid WebAssembly structured control flow at output time.
Source maps let the generated WebAssembly point back to the source positions that produced each instruction. `Module#emitBinary` accepts an optional source map filename; `Module#emitText` handles source map output separately. These are the hooks a compiler needs to make browser debuggers show meaningful source locations.
The debugging API exposes the names of functions, globals, and imports. `Module#getFunctionNames`, `Module#getGlobalNames`, and related methods enumerate the named entities in a module. These are used by the included `wasm-dis` tool to produce readable disassembly.
For expression manipulation, `getExpressionInfo` extracts typed information from an `ExpressionRef` without casting, and `copyExpression` deep-copies an expression subtree. These are useful when transforming an existing module rather than constructing one from scratch.
The Type Definition Lag Problem
The README contains an explicit warning that deserves attention: the Binaryen API evolves fast, and the type definitions and documentation in `index.d.ts` tend to fall out of sync with the implementation despite the maintainers' efforts. The README asks users who depend on binaryen.js and notice a discrepancy to send a pull request updating `index.d.ts` and `README.md` to reflect the current upstream API at `binaryen.js-post.js`.
In practice, this means relying solely on `index.d.ts` for API discovery is unreliable. For any non-trivial use, cross-referencing the upstream Binaryen source at `src/js/binaryen.js-post.js` is necessary. This is the trade-off of automated packaging: the build is current, but the human-maintained documentation layer lags.
Wasm-pack with wasm-bindgen is the main alternative for projects that compile Rust to WebAssembly and want JavaScript bindings. It generates typed JavaScript glue code from a Rust crate rather than providing an imperative module-construction API. The difference is that binaryen.js constructs WebAssembly modules from JavaScript at runtime or build time, while wasm-bindgen consumes Rust code to generate WebAssembly at compile time. The two approaches solve different problems.
How the Build Script Works
The repository's `scripts/bundle.js` file drives the Emscripten compilation of the upstream Binaryen C++ source. The `.gitmodules` file at the repository root links to the upstream Binaryen repository via a git submodule stored in the `binaryen/` directory. When the buildbot runs, it updates the submodule, compiles with Emscripten, bundles the result with esbuild, generates the version-tagged npm release, and publishes it.
The `tests/` directory contains two tests: `tests/sanity` (a quick check that the module loads) and `tests/example` (a runnable version of the README's add function example). The `npm run test` script runs the TypeScript type check on `index.d.ts` first, then runs both tests against the compiled output.
The `bin/` directory holds the Node.js wrappers for each command-line tool. Each wrapper is a small script that invokes the Emscripten-compiled binary through the Node.js process. The tools are registered in `package.json`'s `bin` field, so `npm install -g binaryen` makes `wasm-opt`, `wasm-dis`, and the others available globally on PATH.
Maintenance and License
The last push to the repository was on 2026-09-18. The repository is not archived. The package is at version 132.0.0, tracking upstream Binaryen's versioning. The license is Apache-2.0, which permits commercial use. The repository is maintained by the AssemblyScript team, which uses binaryen.js as the optimization backend for the AssemblyScript TypeScript-to-WebAssembly compiler. There are no GitHub releases in this repository; versioning is tracked through npm and GitHub tags.
The `.gitattributes` file at the repository root marks `index.js` with `linguist-generated=true`, which signals to GitHub that the main file is machine-generated rather than hand-authored. This is accurate: `index.js` is the Emscripten output, not a manually maintained file. The `src/` directory contains the Emscripten JavaScript post-processing additions that are appended to the compiled output, and `.gitmodules` tracks the upstream Binaryen repository as a submodule in the `binaryen/` directory.
Editorial conclusion
binaryen.js is the right dependency when your Node.js or browser tool needs to generate or optimize WebAssembly programmatically: compile a custom language, run `wasm-opt` passes without a native binary, or inspect a `.wasm` file in a portable way. It is not the right choice if you simply want to run WebAssembly code in Node.js or the browser, since the runtime is built into both environments. The API evolves in lockstep with upstream Binaryen releases, and the README explicitly warns that type definitions may lag behind the implementation since the package is a bot. Check `index.d.ts` against the upstream API at `binaryen.js-post.js` before relying on a definition that matters for your use case.
Frequently asked questions
What exactly is WebAssembly and what does binaryen.js do with it?
WebAssembly is a binary instruction format that browsers and Node.js can execute directly at near-native speed. binaryen.js is the Binaryen compiler infrastructure compiled to JavaScript, letting you construct, optimize, validate, and emit WebAssembly modules from a JavaScript API without any native binary.
Why use binaryen.js instead of writing WebAssembly by hand?
binaryen.js provides Binaryen's optimization passes on top of module construction. You build a module with a JavaScript API, call `myModule.optimize()`, and get an optimized binary back. Writing WebAssembly by hand gives you no optimizer and requires deep familiarity with the binary format.
How does the binaryen npm package stay current with upstream Binaryen?
A buildbot checks the upstream Binaryen C++ repository once a day and publishes a new nightly npm version if changes have landed. The version number tracks the upstream Binaryen release number, currently 132. The type definitions in `index.d.ts` are updated by hand and can lag behind the implementation.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/assemblyscript-binaryen-js)