Inspecting WebAssembly Binaries
Every .wasm file is a sequence of numbered sections. Understanding which section contributes what makes it possible to target your optimisation efforts precisely. This lesson shows the tools that surface that information.
The .wasm section layout
Section titled “The .wasm section layout”A WebAssembly binary is divided into up to thirteen standard sections, each with a unique ID. The diagram below shows the most common ones and how they relate to each other.
flowchart TD A[".wasm binary"] --> B["Type section\nfunction signatures"] A --> C["Import section\nJS / host imports"] A --> D["Function section\ntype index per function"] A --> E["Export section\npublic API names"] A --> F["Code section\nactual instructions"] A --> G["Data section\nmemory initialisers"] A --> H["Custom sections\nname debug DWARF producers"]
wasm2wat — human-readable disassembly
Section titled “wasm2wat — human-readable disassembly”The quickest way to read any binary is wasm2wat. It reconstructs the WAT text representation, including function names if a name section is present.
# Dump the full WAT to stdoutwasm2wat add.wasm
# Save to a file for editing or diffingwasm2wat add.wasm -o add.wat
# Generate synthetic names when none are presentwasm2wat add.wasm --generate-nameswasm-objdump — section-by-section inspection
Section titled “wasm-objdump — section-by-section inspection”wasm-objdump -x prints a structured summary of every section: type signatures, imports, exports, and function indices. It is faster than a full disassembly when you only need the module’s public API.
# Full section summarywasm-objdump -x my.wasm
# Disassemble code section only (shows raw instructions)wasm-objdump -d my.wasm
# Show a single sectionwasm-objdump -j export my.wasmwasm-objdump -j import my.wasmtwiggy — size profiling
Section titled “twiggy — size profiling”twiggy is a code-size profiler that attributes every byte in a .wasm binary to a function or section. It is the fastest way to answer “which function is making my binary large?”
# Installcargo install twiggy
# Print the top contributors to binary sizetwiggy top my.wasm
# Show the retaining paths for a specific functiontwiggy paths my.wasm --function "some_large_function"
# Output as JSON for further processingtwiggy top my.wasm --output-format jsonA twiggy top report looks roughly like:
Shallow Bytes | Shallow % | Item----------------+-----------+------------------------------ 14512 | 42.38% | "function names" subsection 8032 | 23.46% | code[42]: some_large_function 3200 | 9.35% | code[17]: decode_utf8Browser DevTools
Section titled “Browser DevTools”Modern browsers ship WebAssembly debugging support directly in DevTools. In Chrome and Firefox you can open Sources → wasm to see a disassembly of every instantiated module, set breakpoints on individual instructions, and inspect local variables and the value stack at each breakpoint.
To get readable function names in DevTools you need either:
- A name section in the binary (produced by
wat2wasm --debug-namesorwasm-opt --debuginfo), or - A DWARF section emitted by Emscripten or clang with
-g.
Trade-offs
Section titled “Trade-offs”| Option | Benefit | Cost |
|---|---|---|
wasm-opt -Oz (most aggressive optimization) | Best size and speed after optimizing | Longer build times, and what you see in wasm2wat/wasm-objdump drifts far from the original source, harder to read |
Keeping the name section (--debug-names) | DevTools and wasm2wat show readable function names | Increases the size of the binary you actually ship |
Common mistakes
Section titled “Common mistakes”- Skipping the inspection step and guessing what’s making a binary large, instead of using
twiggy topto find the real culprit - Turning on aggressive
wasm-optbefore actually knowing which section or function is large or slow - Stripping the name section from the start, so
wasm-objdump,wasm2wat, and DevTools can’t show any readable stack trace at all
💡 Real-world example
Emscripten automatically invokes Binaryen’s
wasm-optwhen you build with-O2/-O3(Emscripten optimization docs); the tools in this lesson (wasm-objdump,twiggy,wasm2wat) are what you reach for afterward when you need to know exactly what that optimized binary contains.