WebAssembly/wabt
The WebAssembly Binary Toolkit
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2d ago
- ✓22+ active contributors
- ✓Distributed ownership (top contributor 23% of recent commits)
Show 3 more →Show less
- ✓Apache-2.0 licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/webassembly/wabt)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/webassembly/wabt on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: WebAssembly/wabt
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/WebAssembly/wabt shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 2d ago
- 22+ active contributors
- Distributed ownership (top contributor 23% of recent commits)
- Apache-2.0 licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live WebAssembly/wabt
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/WebAssembly/wabt.
What it runs against: a local clone of WebAssembly/wabt — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in WebAssembly/wabt | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 32 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of WebAssembly/wabt. If you don't
# have one yet, run these first:
#
# git clone https://github.com/WebAssembly/wabt.git
# cd wabt
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of WebAssembly/wabt and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "WebAssembly/wabt(\\.git)?\\b" \\
&& ok "origin remote is WebAssembly/wabt" \\
|| miss "origin remote is not WebAssembly/wabt (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "include/wabt/ir.h" \\
&& ok "include/wabt/ir.h" \\
|| miss "missing critical file: include/wabt/ir.h"
test -f "include/wabt/binary-reader.h" \\
&& ok "include/wabt/binary-reader.h" \\
|| miss "missing critical file: include/wabt/binary-reader.h"
test -f "include/wabt/binary-writer.h" \\
&& ok "include/wabt/binary-writer.h" \\
|| miss "missing critical file: include/wabt/binary-writer.h"
test -f "CMakeLists.txt" \\
&& ok "CMakeLists.txt" \\
|| miss "missing critical file: CMakeLists.txt"
test -f "include/wabt/common.h" \\
&& ok "include/wabt/common.h" \\
|| miss "missing critical file: include/wabt/common.h"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 32 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~2d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/WebAssembly/wabt"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
WABT (WebAssembly Binary Toolkit) is a C++ suite of command-line tools for parsing, translating, validating, and interpreting WebAssembly binaries. It provides bidirectional conversion between .wasm binary format and .wat text format, plus tools like wasm-decompile (binary→C-like code), wasm-interp (stack-based VM), wasm2c (binary→C source), and wasm-objdump for inspecting module structure. Unlike optimization-focused projects like Binaryen, WABT prioritizes spec compliance and 1:1 round-trip fidelity. Monolithic C++ library with CLI tool wrappers. Core parsing/validation lives in src/ (likely C++ AST/binary readers based on tool structure). Each major tool (wat2wasm, wasm2wat, wasm-interp, wasm-decompile, wasm2c, wasm-objdump, wasm-strip, wasm-validate, wasm-stats, spectest-interp, wast2json) has its own standalone binary. The docs/demo/ folder contains an Emscripten-compiled JavaScript version bundled with CodeMirror for browser-based wat2wasm and wasm2wat experiences.
👥Who it's for
Compiler toolchain developers, WebAssembly runtime implementers, and infrastructure teams building wasm-adjacent tools. Users include projects that need to parse/manipulate wasm binaries without shipping a full optimization framework, and developers writing spec-compliant test suites (via spectest-interp and wast2json). Also used by emscripten and wasm ecosystem projects that need reliable binary-text conversion.
🌱Maturity & risk
Highly mature and production-ready. The project has been stable since the WebAssembly 1.0 spec stabilized (~2017), maintains comprehensive CI via GitHub Actions (.github/workflows/build.yml, build_release.yml), and generates official release artifacts. The codebase is well-structured with clear separation between parser (C++), interpreter, and tool frontends. Active maintenance is evident from spec compliance updates and ongoing CI/CD integration.
Low risk for core stability; primarily single-language (C++ 2.2M+ lines) with minimal external C++ dependencies (see CMakeLists.txt). The main risk factor is the monolithic C++ codebase making contribution friction higher for non-C++ developers. The emscripten-compiled demo (docs/demo/) relies on Node.js dependencies in docs/demo/third_party/package.json (esbuild, CodeMirror v6, split.js), which have normal npm supply-chain exposure. No apparent maintainer bottleneck given the repo's stability.
Active areas of work
Unable to determine recent activity from file listing alone, but the presence of .github/workflows/wabt-cifuzz.yml indicates ongoing fuzzing integration, and the well-maintained docs/demo/ with bundled third-party dependencies suggests active web demo maintenance. The build_release.yml and build_source_release.yml workflows suggest regular release cycles.
🚀Get running
git clone https://github.com/WebAssembly/wabt.git
cd wabt
mkdir build && cd build
cmake ..
make
# Binaries available in build/ directory
./wasm2wat ../test.wasm
./wat2wasm ../test.wat
For the web demo: cd docs/demo/third_party && npm install && npm run build
Daily commands:
Build (native): mkdir build && cd build && cmake .. && make. Run individual tools: ./wasm2wat input.wasm, ./wat2wasm input.wat, ./wasm-interp module.wasm, etc. Build web demo: cd docs/demo/third_party && npm install && npm run build (outputs bundled JS to ../third_party.bundle.js). Run tests: make test (inferred from standard CMake setup) or invoke pytest on Python test scripts.
🗺️Map of the codebase
include/wabt/ir.h— Core intermediate representation definitions for WebAssembly constructs; essential for understanding how WABT models WAT/WASM in memory.include/wabt/binary-reader.h— Primary interface for parsing WebAssembly binary format; entry point for all WASM→WAT conversion workflows.include/wabt/binary-writer.h— Core abstraction for serializing IR back to binary format; handles WAT→WASM compilation pipeline.CMakeLists.txt— Build configuration that defines all tool targets (wat2wasm, wasm2wat, wasm-interp, etc.); required to understand project structure.include/wabt/common.h— Shared utilities, error handling, and type definitions used across the entire codebase.include/wabt/interp/interp.h— Stack-based interpreter implementation for executing WASM; core to wasm-interp tool.include/wabt/decompiler.h— Decompilation engine converting WASM binary to readable C-like pseudocode; critical for wasm-decompile tool.
🛠️How to make changes
Add a new binary analysis tool
- Create a new reader class inheriting from BinaryReader in include/wabt/ (
include/wabt/binary-reader-newtool.h) - Implement the on*() callback methods to extract desired information (
src/binary-reader-newtool.cc) - Add a new tool entry point in the tools/ directory (
tools/wasm-newtool.cc) - Register the new tool executable in CMakeLists.txt (
CMakeLists.txt) - Add documentation for the new tool (
docs/doc/wasm-newtool.1.html)
Add a new WAT language construct or feature
- Define new Expr or other IR node types in include/wabt/ir.h (
include/wabt/ir.h) - Add lexer/parser rules in the appropriate source file for WAT parsing (
src/wat-parser.cc) - Implement binary encoding in binary-writer.cc or binary-writer-spec.cc (
include/wabt/binary-writer.h) - Add corresponding binary decoding in binary-reader-ir.cc (
include/wabt/binary-reader-ir.h) - Register feature flag if gated in include/wabt/feature.def (
include/wabt/feature.def)
Extend the interpreter with new instructions or WASI functions
- Add instruction handler in interp-inl.h or new instruction group (
include/wabt/interp/interp-inl.h) - Implement stack operations and value manipulation (
include/wabt/interp/interp-math.h) - For WASI: add function binding in interp-wasi.h (
include/wabt/interp/interp-wasi.h) - Update interp.h with new State or Context fields if needed (
include/wabt/interp/interp.h) - Add tests in test/ directory (if test suite organized there) (
test/)
Improve decompiler output quality
- Enhance naming heuristics in decompiler-naming.h (
include/wabt/decompiler-naming.h) - Refine pseudocode generation logic in decompiler.h/cc (
include/wabt/decompiler.h) - Add pattern recognition rules in decompiler-ast.h (
include/wabt/decompiler-ast.h) - Update wasm-decompile tool with new options if needed (
tools/wasm-decompile.cc)
🔧Why these technologies
- C++11/14 with custom memory management — Enables direct binary format manipulation with zero-copy parsing and fine-grained control over heap allocation for embedded/WASM compilation targets
- Stack-based interpreter design — Matches the WebAssembly specification's execution model exactly; simplifies correctness verification and spec compliance
- Visitor pattern for IR traversal — Enables independent passes (validation, naming, decompilation) without coupling to IR node types
- CMake build system — Supports cross-platform compilation to multiple targets (native, Emscripten, WASI)
- Modular binary readers (specialized readers per use case) — Avoids overhead of full IR construction when only metadata/stats/interpretation is needed
⚖️Trade-offs already made
- Full IR construction vs. streaming binary processing
- Why: Full IR enables arbitrary passes and transformations; streaming would be faster but limits tool capabilities
- Consequence: undefined
🪤Traps & gotchas
No required environment variables are documented in the visible file list. CMake will auto-detect the C++ compiler; ensure a recent C++11-compatible compiler (clang/gcc) is available. The web demo requires Node.js 14+ for npm. The Emscripten-compiled demo (docs/demo/libwabt.wasm + libwabt.js) is pre-built; rebuilding it requires Emscripten SDK setup (not documented in visible files, likely in a separate build step). The .gitmodules suggests git submodules are in use; clone with git clone --recursive to fetch them. Python test infrastructure requires Python 3 and packages listed in any requirements.txt (not visible in file list).
🏗️Architecture
💡Concepts to learn
- WebAssembly Binary Format (.wasm) — The core format WABT parses and generates; understanding the binary structure (module header, sections, instruction opcodes) is essential to using any tool.
- WebAssembly Text Format (.wat / S-expressions) — The human-readable source format; wat2wasm and wasm2wat convert between this and binary, so understanding syntax (modules, imports, instructions, call conventions) is critical.
- Stack-based Virtual Machine (Interpreter) — WABT's wasm-interp executes wasm modules using a stack-based computation model; understanding operand stacks, local/global state, and control flow (blocks, loops, calls) is necessary to use the interpreter correctly.
- Abstract Syntax Tree (AST) / IR Representation — WABT parses binary/text into an internal C++ AST before codegen or interpretation; understanding the AST node structure (expressions, instructions, type annotations) helps when extending tools.
- Validation / Type Checking — wasm-validate and the parser enforce WebAssembly type safety rules (opcode-operand stack consistency, function signatures, control flow reachability); WABT's validator is spec-compliant.
- Emscripten Compilation (C++ → WebAssembly → JavaScript) — The docs/demo/ version of WABT is compiled to wasm via Emscripten, then wrapped in JS; understanding this toolchain is necessary to rebuild or extend the browser demo.
- Spec Test Format (WAST / JSON) — The wast2json tool and spectest-interp consume the official WebAssembly spec test suite; understanding the .wast format (comments, assert statements, module definitions) is needed for test integration.
🔗Related repos
WebAssembly/binaryen— Direct alternative for wasm binary manipulation; Binaryen focuses on optimization and transformation while WABT prioritizes spec compliance and round-trip fidelity.WebAssembly/spec— Official WebAssembly specification repository; WABT is the reference implementation toolkit that validates against this spec via spectest-interp and wast2json.emscripten-core/emscripten— Major consumer of WABT; emscripten uses wasm2c and wasm2wat in its toolchain to compile C/C++ to WebAssembly and back.WebAssembly/wasm-c-api— Companion spec for C API interop with wasm runtimes; complements WABT's wasm2c tool for embedding wasm in C/C++ applications.bytecodealliance/wasmtime— Production wasm runtime; WABT's text/binary tools are often used upstream to validate and prepare modules for execution in Wasmtime.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add fuzzer documentation and integration guide in docs/
The repo has 5 fuzzers (read_binary_interp_fuzzer.cc, read_binary_ir_fuzzer.cc, wasm2wat_fuzzer.cc, wasm_objdump_fuzzer.cc, wat2wasm_fuzzer.cc) in fuzzers/ directory and fuzzing seed data in fuzz-in/, but no documentation explaining how to build, run, or contribute to fuzzing efforts. This is a high-value contribution for security-conscious contributors and matches the SECURITY.md file's existence.
- [ ] Create docs/fuzzing.md documenting how to build fuzzers with libFuzzer/ASAN
- [ ] Document the purpose of each fuzzer in fuzzers/ directory
- [ ] Explain how to add/update seed data in fuzz-in/ directories
- [ ] Reference the existing wabt-cifuzz.yml workflow and explain its integration
- [ ] Add instructions for running fuzzers locally and reporting issues
Add GitHub Action for building and testing the web demo (docs/demo/)
The repo has an interactive web demo with complex dependencies (CodeMirror 6, esbuild) in docs/demo/third_party/package.json, but there's no dedicated CI workflow to verify the demo builds correctly. The build.yml workflow likely doesn't cover the demo's npm build step. This prevents regressions in the web demo from being caught automatically.
- [ ] Create .github/workflows/build_demo.yml that runs on pushes to docs/demo/
- [ ] Add steps to: cd docs/demo/third_party && npm install && npm run build
- [ ] Verify libwabt.js and libwabt.wasm are generated correctly
- [ ] Test both wat2wasm and wasm2wat demo pages load without errors
- [ ] Add a cache step for npm dependencies to speed up CI runs
Add integration tests for decompiler feature (docs/decompiler.md exists, but no tests found)
The repo documents a wasm-decompile tool (docs/doc/wasm-decompile.1.html exists and docs/decompiler.md exists), but searching the file structure shows no corresponding test files in test/ or examples/. This suggests the decompiler lacks automated test coverage despite being a documented feature.
- [ ] Create test/ subdirectory with decompiler test cases (if it doesn't exist)
- [ ] Add 3-5 test .wasm binaries with known decompile outputs
- [ ] Create a test script that runs wasm-decompile against each test binary
- [ ] Add reference .c or .txt files showing expected decompilation output
- [ ] Integrate the decompiler tests into the build.yml workflow's test step
🌿Good first issues
- Add comprehensive command-line help text / man page generation for wasm-stats (docs/doc/wasm-stats.1.html exists but tool may lack --help parity) — start in src/ tool implementation and docs/doc/.
- Expand wasm-objdump feature parity with native objdump (e.g., --headers, --relocs support for relocation sections) — requires extending the binary format parser in src/ and adding CLI flags.
- Create a Python binding / wrapper module for libwabt to enable spec test scripts to directly invoke parsing/validation without shell-spawning wat2wasm and wasm-validate — requires CMake SWIG/ctypes setup and Python package scaffolding.
⭐Top contributors
Click to expand
Top contributors
- @sbc100 — 23 commits
- @zherczeg — 19 commits
- @shravanrn — 11 commits
- @SoniEx2 — 10 commits
- @sumleo — 8 commits
📝Recent commits
Click to expand
Recent commits
03a00a1— Bump version to 1.0.41 (#2746) (sbc100)7773e5c— Include error information on error opening output file (#2745) (sbc100)282e2e5— Validator: thread table limits throughOnReturnCallIndirect(#2744) (ggreif)77a95c8— Use unsigned line info in Locations (#2738) (zherczeg)6dc6cfd— Remove debug-parser option and other unused variables (#2739) (zherczeg)ec3eac8— [lexer] Simplify GetLineOffsets (#2735) (zherczeg)2f731a7— Add declaration limit checks to parser (#2736) (zherczeg)41db004— Move filename out of Location (#2728) (zherczeg)0756e49— [wast-parser] Optimize Consume() (#2727) (zherczeg)5551e79— Fix wat2wasm demo by removing call to non-existent module.resolveNames (#2726) (yuvraj-sahu)
🔒Security observations
The WABT codebase shows generally good security practices with a public repository and defined security policy. However, there are moderate concerns with dependency management in the web demo components. The main issues are: (1) use of caret version specifiers allowing automatic updates without review, (2) loose security reporting policy preferring public issues over private disclosure, and (3) sourcemaps enabled in production builds. The compiled C/C++ toolkit itself (the primary component) shows no immediate vulnerabilities in the provided context. Recommendations include implementing stricter dependency pinning, establishing a private security disclosure process, and disabling sourcemaps for production web assets.
- Medium · Caret Dependencies in package.json —
docs/demo/third_party/package.json. The package.json uses caret (^) version specifiers for all dependencies, which allows minor and patch version updates automatically. This could introduce breaking changes or vulnerabilities from transitive dependencies without explicit review. Versions like ^6.10.3, ^6.2.5, etc. may pull in unexpected updates. Fix: Use exact version pinning (remove ^) or at minimum use ~version specifiers to limit to patch updates. Implement dependency pinning with lock files and regular security audits. Use 'npm audit' regularly to identify vulnerabilities. - Medium · Build Script Uses Unverified esbuild —
docs/demo/third_party/package.json - build script. The build script directly invokes esbuild without integrity verification or explicit version locking beyond package.json. The esbuild package (^0.27.4) could be compromised or have vulnerabilities. There's no evidence of lock file usage (.package-lock.json exists but content not shown). Fix: Ensure package-lock.json is committed to version control and verified. Use npm ci instead of npm install in CI/CD. Consider using npm's audit-signatures feature. Review esbuild release notes before updates. - Low · Loose Security Policy —
SECURITY.md. The SECURITY.md file indicates security vulnerabilities should be reported via public GitHub issues rather than a private disclosure process. This could allow attackers to become aware of security issues before patches are available. Fix: Implement a private security reporting mechanism (e.g., GitHub Security Advisories, security@wabt.org email). Follow responsible disclosure practices with an embargo period before public disclosure. - Low · Sourcemaps Enabled in Production Build —
docs/demo/third_party/package.json - build script. The esbuild configuration includes '--sourcemap' flag in the build script. Sourcemaps expose original source code and can aid attackers in understanding implementation details and finding vulnerabilities. Fix: Disable sourcemaps for production builds, or generate them separately and restrict access. If sourcemaps are needed for debugging, serve them from a secure location with authentication. - Low · ISC License with Broad Dependencies —
docs/demo/third_party/package.json. The third-party package uses ISC license while bundling multiple GPL/Copyleft-compatible CodeMirror packages. License compliance should be verified for distribution. Fix: Verify license compatibility of all bundled dependencies. Document all licenses in the distribution. Consider updating license field to reflect actual compliance requirements.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.