wabt — The Binary Toolkit
wabt — the WebAssembly Binary Toolkit — is the reference implementation for the WAT text format. Every conversion, inspection, or validation task that touches the text ↔ binary boundary goes through one of its four main programs.
wat2wasm
Section titled “wat2wasm”wat2wasm is the primary compiler. It parses .wat source, type-checks it, and emits a conforming .wasm binary. Useful flags include --debug-names (preserve $name annotations in the binary’s name section) and --output / -o to control the output file.
# Basic compilationwat2wasm add.wat -o add.wasm
# Keep debug names in the binarywat2wasm add.wat --debug-names -o add.debug.wasm
# Validate only, don't write outputwat2wasm add.wat --no-check=false --output=/dev/nullwasm2wat
Section titled “wasm2wat”wasm2wat reverses the process: it reads a .wasm binary and emits readable WAT text. This is invaluable when you want to inspect what a higher-level compiler (Emscripten, wasm-pack, etc.) actually produced.
# Disassemble to stdoutwasm2wat add.wasm
# Disassemble to a filewasm2wat add.wasm -o add.wat
# Include source locations from the DWARF sectionwasm2wat add.wasm --generate-nameswasm-objdump
Section titled “wasm-objdump”wasm-objdump prints structured metadata about a .wasm file — its section layout, imports, exports, and function signatures — without producing a WAT disassembly. Use -x for a full summary or -d to disassemble only the code section.
# Full section summarywasm-objdump -x add.wasm
# Disassemble code section onlywasm-objdump -d add.wasm
# Show only the export sectionwasm-objdump -j export add.wasmA typical -x output looks like this:
add.wasm: file format wasm 0x1
Section Details:
Type[1]: - type[0] (i32, i32) -> i32Function[1]: - func[0] sig=0Export[1]: - func[0] <add> -> "add"Code[1]: - func[0] size=7wasm-validate
Section titled “wasm-validate”wasm-validate checks that a binary conforms to the WebAssembly specification. It exits with code 0 on success and prints a diagnostic on failure. Use it in CI to catch corrupted or invalid modules before they reach production.
# Validate a modulewasm-validate add.wasm# → add.wasm: OK
# Validate a module with a future proposalwasm-validate --enable-threads shared.wasmRun it — magic bytes and binary length
Section titled “Run it — magic bytes and binary length”The four bytes at offset 0 of every valid .wasm file are 00 61 73 6d — the module magic (\0asm). The runnable below compiles a minimal WAT module and logs both the binary length and those four magic bytes, making the compilation process concrete.
Trade-offs
Section titled “Trade-offs”| Option | Benefit | Cost |
|---|---|---|
wasm-opt -Oz (most aggressive optimization, after wat2wasm) | Best size and speed | Longer build times, and the resulting binary drifts far from the original .wat, harder to debug |
Keeping --debug-names during wat2wasm | wasm2wat/wasm-objdump show readable function names | Increases the size of the binary you ship to users |
Common mistakes
Section titled “Common mistakes”- Compiling
.watto.wasmand shipping it directly without ever runningwasm-opt, missing a nearly-free size reduction - Running
wasm-validateonly after deploying, instead of validating every module in CI before shipping - Leaving
--debug-nameson in production builds without weighing the size trade-off it introduces
💡 Real-world example
After a step equivalent to
wat2wasm, Emscripten automatically invokes Binaryen’swasm-optwhen building with-O2/-O3(Emscripten optimization docs) — the same optimization principle this lesson’s WABT-based pipeline applies by hand.