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.