Setting Up the Toolchain

2.1 Essential Tools

WABT (WebAssembly Binary Toolkit) wat2wasm, wasm2wat, wasm-objdump, wasm-interp, wasm2c, wasm-validate wasm-tools (Bytecode Alliance)

Parse, print, validate, strip, compose, and component tooling (wasm-tools print/parse/validate/component/compose/metadata)

wasm-opt (optimizer), wasm-merge, wasm-metadce, wasm2js Emscripten SDK (emsdk) C/C++ → Wasm + JS glue Rust + wasm-pack + wasm-bindgen Rust → Wasm for JS environments Clang toolchain targeting WASI Wasmtime / Wasmer / WasmEdge Run Wasm outside the browser JS host for testing twiggy, wasm-snip Code size analysis and trimming

JavaScript tooling for components (transpile, run) cargo-component, wit-bindgen, wac Component Model tooling

2.2 Installation

# WABT
brew install wabt                # or apt install wabt / download releases from GitHub

# Binaryen
brew install binaryen

# wasm-tools, wasmtime (via cargo or installers)
curl https://wasmtime.dev/install.sh -sSf | bash
cargo install wasm-tools

# Emscripten
git clone https://github.com/emscripten-core/emsdk.git && cd emsdk
./emsdk install latest && ./emsdk activate latest
source ./emsdk_env.sh            # Windows: emsdk_env.bat
emcc -v

# Rust
curl https://sh.rustup.rs -sSf | sh
rustup target add wasm32-unknown-unknown wasm32-wasip1 wasm32-wasip2
cargo install wasm-pack wasm-bindgen-cli cargo-component

# Node tooling
npm install -g @bytecodealliance/jco assemblyscript

2.3 Your First Module (Handwritten WAT)

Servers must send .wasm files with Content-Type: application/wasm for instantiateStreaming.

;; add.wat
(module
  (func $add (export "add") (param $a i32) (param $b i32) (result i32)
    local.get $a
    local.get $b
    i32.add))
wat2wasm add.wat -o add.wasm       # text → binary (tiny: ~40 bytes)
wasm2wat add.wasm                  # binary → text
wasm-objdump -x add.wasm           # inspect sections
wasmtime --invoke add add.wasm 2 3 # run outside the browser → 5
<!-- index.html: serve over HTTP (e.g., `npx serve`); file:// won't work for fetch -->
<script type="module">
  const { instance } = await WebAssembly.instantiateStreaming(fetch("add.wasm"));
  console.log(instance.exports.add(2, 3)); // 5
</script>