Overview
What is By-Example Learning?
By-example learning is a code-first approach designed for experienced developers who want to pick up WebAssembly rapidly. Instead of lengthy theoretical explanations, you see working code first, observe what it does, and build understanding through annotated examples that show every step.
This tutorial assumes you already know at least one programming language well and want to understand WebAssembly from WAT binary fundamentals up through the modern component model and WASIp3 async model.
What is WebAssembly?
WebAssembly (Wasm) is a portable binary instruction format — a compilation target for multiple source languages — designed to execute at near-native speed in browsers, servers, and edge runtimes. The W3C ratified WebAssembly 3.0 on September 17, 2025, standardizing nine new features including WasmGC, tail calls, exception handling, multiple memories, Memory64, Relaxed SIMD, typed references, deterministic profile, and JS String Builtins.
Wasm is not a programming language you write by hand in production. It is the target your toolchain produces: Rust through wasm-pack, C/C++ through Emscripten, AssemblyScript through asc, Kotlin through the Kotlin/Wasm compiler, and dozens more. Understanding the binary format — WebAssembly Text (WAT) format — gives you a mental model of what every toolchain produces and how the runtime executes it.
Learning Path
%% Color Palette: Blue #0173B2, Orange #DE8F05, Teal #029E73, Purple #CC78BC, Brown #CA9161
graph TD
A["Beginner<br/>Examples 1-28<br/>WAT Fundamentals + JS API"] --> B["Intermediate<br/>Examples 29-57<br/>Rust Toolchain + Emscripten + WASI"]
B --> C["Advanced<br/>Examples 58-85<br/>Threads + SIMD + WasmGC + Component Model"]
style A fill:#0173B2,color:#fff
style B fill:#DE8F05,color:#fff
style C fill:#029E73,color:#fff
Progress from WAT binary fundamentals through production toolchains to cutting-edge features. Each level builds on the previous.
Coverage Philosophy
This tutorial covers WebAssembly comprehensively through practical, annotated examples. The coverage percentage reflects concept breadth — focus is on outcomes and understanding, not duration.
What's Covered
- WAT Fundamentals: Module structure, value types, functions, control flow, memory model
- JavaScript API:
WebAssembly.instantiateStreaming,WebAssembly.Memory, imports/exports - AssemblyScript: Typed subset of TypeScript compiling to Wasm (NOT the same as TypeScript)
- Rust + wasm-pack + wasm-bindgen: The dominant Wasm-from-Rust toolchain (wasm-bindgen 0.2.120)
- Emscripten: C/C++ to Wasm compilation (Emscripten 5.0.6, requires Node.js 18.3.0+)
- Performance patterns: Boundary optimization, SIMD, Web Workers, wasm-opt
- WASI: WASIp1 (stable legacy), WASIp2 (current stable, January 2024), WASIp3 (February 2026, native async)
- Debugging: DWARF debug info, Chrome DevTools WASM extension
- Threads: SharedArrayBuffer, atomic operations, Emscripten pthreads, wasm-bindgen-rayon
- SIMD: Fixed 128-bit SIMD (universally available), Relaxed SIMD (Chrome/Firefox/Edge shipped)
- WasmGC: Garbage collection for managed-language compilation (Baseline Dec 11, 2024)
- Exception handling:
throw/catch/exnref, JSWebAssembly.TagAPI (Wasm 3.0) - Component Model: WIT interfaces,
wit-bindgenv0.57.1, WASIp2 components, composition - Production: Memory64, multi-memory, Cloudflare Workers deployment, ESM source phase imports
What's NOT Covered
- Wasm interpreter internals: Spectest, reference interpreter implementation details
- Compiler backend specifics: LLVM WebAssembly target internals
- Browser engine JIT: Cranelift, V8 Liftoff/TurboFan WebAssembly tiers
- All source languages: Go, C#, Python, Java, Dart — covered in toolchain-specific guides
Tutorial Structure: 85 Examples Across 3 Levels
Beginner (Examples 1-28: WAT Fundamentals + JS API + AssemblyScript)
Focus: Understanding the Wasm binary model and JavaScript integration
Learn the WAT text format (the human-readable representation of Wasm binaries), the JavaScript WebAssembly API, linear memory, and AssemblyScript as a typed entry point for writing Wasm directly. By example 28, you understand what every compiled .wasm file is made of.
Key topics: Module structure, value types, functions, control flow, WABT tooling, instantiateStreaming, memory pages, string encoding, AssemblyScript setup and types.
Intermediate (Examples 29-57: Rust Toolchain + Emscripten + Performance + WASI)
Focus: Production toolchains and real-world patterns
Master wasm-pack and wasm-bindgen for Rust-to-Wasm compilation, Emscripten for C/C++ porting, performance optimization techniques, and WASI for server-side Wasm execution. By example 57, you can build, optimize, and debug production Wasm modules.
Key topics: #[wasm_bindgen], JS class exports, web-sys, async Rust in Wasm, Emscripten C interop, wasm-opt, Web Workers, WASI file I/O, DWARF debugging.
Advanced (Examples 58-85: Threads + SIMD + WasmGC + Component Model + Production)
Focus: Cutting-edge Wasm 3.0 features and deployment
Explore shared memory and atomics, SIMD vector operations, WasmGC typed references, exception handling, the Component Model with WIT interfaces, WASIp3 async, and production deployment patterns. By example 85, you understand the full breadth of the WebAssembly ecosystem as of 2025-2026.
Key topics: Atomic operations, futex primitives, fixed/relaxed SIMD, GC struct/array types, throw/catch, WIT interface files, wit-bindgen, component composition, Cloudflare Workers, ESM source phase imports.
Prerequisites
- Familiarity with at least one compiled or systems language (C, C++, Rust, Go, Java)
- Basic JavaScript knowledge for the JS API sections (Examples 9-16, 37-38)
- Rust basics helpful for Examples 29-38 (see the Rust By Example tutorial)
- C basics helpful for Examples 39-44 (just enough to read function signatures)
wabtinstalled for WAT examples:brew install wabtor download from github.com/WebAssembly/wabt- A modern browser (Chrome 119+, Firefox 120+, Safari 18.2+) for browser-API examples
Toolchain Versions Referenced
| Tool | Version | Notes |
|---|---|---|
| WABT | 1.0.40 | wat2wasm, wasm-objdump, wasm-decompile |
| Emscripten | 5.0.6 | Requires Node.js 18.3.0+ |
| wasm-bindgen | 0.2.120 | CLI version MUST match crate version exactly |
| wasm-pack | 0.14.0 | WASI support, macOS ARM support |
| Binaryen/wasm-opt | version_129 | 10-20% typical size reduction |
| AssemblyScript | 0.28.x | NOT TypeScript — explicit low-level types |
| wit-bindgen | v0.57.1 | WIT guest bindings generator |
| Wasmtime | v44.0.0 | WASIp2 + experimental WASIp3 |
| wasm-feature-detect | 1.8.0 | Browser feature detection |
Examples by Level
Beginner (Examples 1–28)
- Example 1: Minimal WAT Module
- Example 2: Value Types in WAT
- Example 3: Functions in WAT
- Example 4: Converting WAT to .wasm Binary with wat2wasm
- Example 5: Inspecting a .wasm Binary with wasm-objdump
- Example 6: Decompiling .wasm to C-like Pseudocode with wasm-decompile
- Example 7: Control Flow in WAT
- Example 8: Recursive Fibonacci in WAT
- Example 9: Loading .wasm with WebAssembly.instantiateStreaming
- Example 10: Fallback: fetch + WebAssembly.instantiate
- Example 11: Calling Exported Wasm Functions from JavaScript
- Example 12: Importing JavaScript Functions into a Wasm Module
- Example 13: WebAssembly.Module and WebAssembly.Instance Lifecycle
- Example 14: WebAssembly.compile for Pre-compilation
- Example 15: WebAssembly.validate for Binary Validity Check
- Example 16: Runtime Feature Detection with wasm-feature-detect
- Example 17: Declaring Memory in WAT
- Example 18: WebAssembly.Memory Constructor
- Example 19: Reading and Writing Wasm Memory from JavaScript via Typed Arrays
- Example 20: Memory Grow — WAT and JavaScript
- Example 21: Memory Layout — Pointer and Length Convention
- Example 22: UTF-8 String Encoding Across the Wasm–JS Boundary
- Example 23: Exporting and Importing Memory
- Example 24: Setting Up AssemblyScript
- Example 25: Writing Typed Functions in AssemblyScript
- Example 26: Compiling AssemblyScript and Loading in Browser
- Example 27: AssemblyScript Linear Memory — store, load, memory.size
- Example 28: StaticArray vs Heap Arrays in AssemblyScript
Intermediate (Examples 29–57)
- Example 29: Rust Wasm Project Setup with wasm-pack
- Example 30:
#[wasm_bindgen]on Functions - Example 31: Passing Strings Across the Wasm–JS Boundary
- Example 32: Passing Vec
and &[u8] Slices - Example 33: Exporting Rust Structs as JavaScript Classes
- Example 34: Calling Browser Web APIs from Rust Using web-sys
- Example 35: Calling JS Functions from Rust with js_sys and extern "C"
- Example 36: wasm-pack Build Targets
- Example 37: Consuming wasm-pack Output in Vite and Next.js
- Example 38: Async Rust in Wasm — wasm-bindgen-futures
- Example 39: Hello World with Emscripten 5.0.6
- Example 40: Exporting C Functions to JS with Emscripten
- Example 41: Calling JavaScript from C with emscripten_run_script and EM_JS
- Example 42: malloc and free in Emscripten — Passing Allocated Buffers
- Example 43: Porting a C Image Processing Function — Grayscale
- Example 44: Dynamic Memory Growth in Emscripten
- Example 45: Minimizing Wasm–JS Boundary Crossings
- Example 46: postMessage and SharedArrayBuffer for Web Workers
- Example 47: Offloading Computation to a Web Worker
- Example 48: wasm-opt Optimization Passes
- Example 49: Measuring Wasm Performance with performance.now
- Example 50: Streaming Compilation vs Fetch-Then-Compile
- Example 51: WASI Hello World in Rust — Target wasm32-wasip1
- Example 52: Running WASI Modules with wasmtime run
- Example 53: WASI File I/O — Reading and Writing Files
- Example 54: Running WASI Modules in Node.js with node:wasi
- Example 55: Generating DWARF Debug Info with Emscripten
- Example 56: Separating Debug Info from Production Binary
- Example 57: Chrome DevTools WASM Debugging
Advanced (Examples 58–85)
- Example 58: Shared Memory in WAT
- Example 59: Atomic Operations in WAT
- Example 60: Wasm Futex — memory.atomic.wait and memory.atomic.notify
- Example 61: Web Workers and SharedArrayBuffer for Parallel Wasm
- Example 62: Emscripten pthreads — -pthread Compilation
- Example 63: Rust Parallel Wasm with wasm-bindgen-rayon
- Example 64: Fixed 128-bit SIMD in WAT
- Example 65: Relaxed SIMD in WAT
- Example 66: SIMD with Emscripten — -msimd128 Flag
- Example 67: AssemblyScript SIMD with v128 Type
- Example 68: Runtime SIMD Detection and Alternate Module Loading
- Example 69: WasmGC Types in WAT — struct.new and array.new
- Example 70: Typed Function References — call_ref and ref.func
- Example 71: Kotlin/Wasm and WasmGC in the Browser
- Example 72: Exception Handling in WAT
- Example 73: Catching Wasm Exceptions in JavaScript
- Example 74: JS String Builtins — Zero-Glue String Operations
- Example 75: Writing a WIT Interface File
- Example 76: Generating Rust Guest Bindings from WIT with wit-bindgen
- Example 77: Building a WASIp2 Component with cargo component
- Example 78: Composing Two Components with wac plug
- Example 79: Running a Composed Component with Wasmtime
- Example 80: JavaScript Component Guest with componentize-js
- Example 81: WASIp3 Async — future
and stream in WIT - Example 82: Memory64 — 64-bit Addressing in WAT
- Example 83: Multi-Memory Modules — Separate Internal and Shared Memory
- Example 84: Deploying WASI Components to Cloudflare Workers and Fastly Compute
- Example 85: ESM Source Phase Imports — import source mod from './mod.wasm'
Last updated April 28, 2026