Tutorial
WebAssembly Tutorial
A practical tutorial on WebAssembly using Rust, covering browser and server-side use. Walks through the WAT text format, linear memory, JS interop with wasm-bindgen, wasm-pack, WASI, server runtimes (Wasmtime, Wasmer), the Component Model, and the tooling and patterns that keep real Wasm modules small, fast, and maintainable.
Chapters
01
Introduction: What WebAssembly Is and Why It Exists
02
WAT and Binary: Inside a Wasm Module
03
Linear Memory: Moving Data Across the Boundary
04
Rust to Wasm: Compiling Without Helpers
05
JavaScript Interop: Wasm in the Browser
06
wasm-bindgen: The Rust–JS Bridge
07
wasm-pack and Bundlers: Shipping Wasm to npm
08
WASI: Wasm Beyond the Browser
09
Server Runtimes: Wasmtime, Wasmer, WasmEdge
10
The Component Model: Composable Wasm
11
The Ecosystem: Languages, Tools, and Real Uses
12
Best Practices: Performance, Size, and Anti-Patterns
About this tutorial
A practical tour of WebAssembly using Rust, from your first compiled module to running Wasm on a server with WASI.
Who This Is For
- Developers who've heard Wasm is "fast" and "portable" and want to see what that actually means
- Rust programmers curious about compilation targets beyond native binaries
- Engineers evaluating Wasm for edge compute, plugin systems, or sandboxed code execution
- Anyone building for the browser who's pushing the limits of JS performance
Contents
Fundamentals
- Introduction: What Wasm is, why it exists, toolchain, first module
- WAT and Binary: The text format, binary structure, module anatomy
- Linear Memory: Memory model, passing strings and arrays across the boundary
Core Concepts
- Rust to Wasm: Compiling Rust to Wasm with no glue code
- JavaScript Interop: Instantiating Wasm in browsers, calls in both directions
- wasm-bindgen: The Rust–JS bridge, JsValue, complex types, async
- wasm-pack and Bundlers: Building for npm, webpack, Vite
Advanced
- WASI: System interface for server-side Wasm
- Server Runtimes: Wasmtime, Wasmer, WasmEdge
- The Component Model: WIT, composable Wasm
Ecosystem
- Ecosystem: Other source languages, tooling, real-world uses
Mastery
- Best Practices: Performance, size, debugging, anti-patterns
How to Use This Tutorial
- Read sequentially. Each chapter builds on the last
- Build every example. Wasm is a concrete artifact; poking at real
.wasmfiles makes the concepts click - Install the tooling early. Chapter 1 gets you a working toolchain in about 10 minutes
Quick Reference
Toolchain Setup
# Rust with the Wasm target
rustup target add wasm32-unknown-unknown # for browsers
rustup target add wasm32-wasip1 # for WASI (server)
# wasm-bindgen CLI (browser interop)
cargo install wasm-bindgen-cli
# wasm-pack (npm-friendly builds)
cargo install wasm-pack
# WABT (WAT <-> binary)
brew install wabt # macOS
# or build from github.com/WebAssembly/wabt
# A server runtime
brew install wasmtime # or: curl https://wasmtime.dev/install.sh -sSf | bash
Hello Wasm (Rust, no helpers)
// src/lib.rs
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
a + b
}
# Cargo.toml
[lib]
crate-type = ["cdylib"]
cargo build --target wasm32-unknown-unknown --release
# target/wasm32-unknown-unknown/release/hello.wasm
Inspect it:
wasm2wat target/wasm32-unknown-unknown/release/hello.wasm | head
Common Patterns
// Export a function
#[no_mangle]
pub extern "C" fn multiply(a: i32, b: i32) -> i32 { a * b }
// Import a JS function (browser)
extern "C" {
fn console_log(ptr: *const u8, len: usize);
}
// With wasm-bindgen (see Chapter 6):
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Hello, {name}!")
}
# Run a WASI module on the server
wasmtime run my_module.wasm
# Optimize size and speed
wasm-opt -O3 -o out.wasm in.wasm
# Disassemble to text
wasm2wat in.wasm -o out.wat
Additional Resources
- WebAssembly.org: official specs and resources
- Rust and WebAssembly book: the canonical Rust→Wasm tutorial
- MDN WebAssembly docs: browser-facing reference
- Wasmtime docs: server-side runtime
- Bytecode Alliance: stewards of Wasmtime, WASI, Component Model
- wasm-bindgen guide: Rust–JS interop deep reference
Versions
This tutorial is written for Rust 1.75+, wasm-bindgen 0.2+, wasm-pack 0.12+, and Wasmtime 20+. The Component Model examples assume WASI Preview 2. Older versions work with adjustments, noted where relevant.