WebAssembly Reference
Free reference guide: WebAssembly Reference
About WebAssembly Reference
This WebAssembly Reference provides a structured, searchable guide to Wasm development organized into six categories: Basics, Modules, Memory, Tables, Types, and WASI. The Basics section covers the essential JavaScript API for loading and running Wasm modules, including WebAssembly.instantiate() for compiling and instantiating from an ArrayBuffer, WebAssembly.compile() for ahead-of-time compilation, importObject construction for passing host functions and memory into Wasm, and the WAT (WebAssembly Text Format) representation for human-readable module definitions.
The reference details Wasm module internals including function definitions with (func), exports with (export), imports with (import), and global mutable variables with (global). The Memory section explains the linear memory model where each page is 64KB, covering WebAssembly.Memory construction, memory.grow for dynamic expansion, ArrayBuffer-based access via memory.buffer, DataView for multi-type read/write operations, and string passing between JavaScript and Wasm using TextEncoder/TextDecoder. The Tables section documents indirect function calls via WebAssembly.Table and call_indirect for dynamic dispatch patterns.
Type system coverage includes the four value types (i32, i64, f32, f64), memory load/store operations (i32.load, i32.store), and type conversion instructions (wrap, extend, convert, trunc). The WASI section introduces the WebAssembly System Interface for running Wasm outside the browser, covering fd_read/fd_write for file descriptor I/O, args_get for command-line argument access, and the wasi_snapshot_preview1 import namespace. This makes the reference valuable for systems programmers, performance engineers, and anyone compiling C/C++/Rust to Wasm.
Key Features
- JavaScript Wasm API: WebAssembly.instantiate(), compile(), importObject construction, and instance.exports function calling
- WAT text format syntax with complete module structure: (module), (func) with params/results, (export), (import), (global)
- Linear memory model: WebAssembly.Memory creation with page sizing, memory.grow, ArrayBuffer views, and DataView typed access
- String passing between JavaScript and Wasm using TextEncoder/TextDecoder with memory offset management
- WebAssembly.Table and call_indirect for function pointer tables and dynamic dispatch patterns
- Complete type system: i32/i64 integers, f32/f64 floats, load/store memory operations, and type conversion instructions
- WASI system interface: fd_read/fd_write file I/O, args_get argument access, wasi_snapshot_preview1 import namespace
- Searchable and filterable by category with practical code examples for each API and instruction
Frequently Asked Questions
What is the difference between WebAssembly.instantiate() and WebAssembly.compile()?
WebAssembly.instantiate() both compiles and creates an instance in one step, returning a {module, instance} pair. WebAssembly.compile() only compiles the bytes into a Module object without instantiating it, which is useful when you need to create multiple instances from the same module with different import objects. For streaming compilation from a fetch response, use WebAssembly.instantiateStreaming() which is more efficient as it compiles while downloading.
How does WebAssembly linear memory work and why is it limited to 64KB pages?
Wasm linear memory is a contiguous, growable ArrayBuffer that both JavaScript and Wasm code can read and write. It is allocated in pages of 64KB (65,536 bytes). You specify initial and optional maximum pages at creation: new WebAssembly.Memory({ initial: 1, maximum: 10 }) starts with 64KB, growable to 640KB. The page-based model simplifies bounds checking and provides deterministic memory layout. Access from JS via memory.buffer as a Uint8Array, Int32Array, or DataView.
How do I pass strings between JavaScript and WebAssembly?
Wasm has no native string type, so strings must be encoded into linear memory. To send a string from JS to Wasm: use TextEncoder to convert to UTF-8 bytes, then copy those bytes into the Wasm memory buffer at a known offset. To read a string from Wasm: the Wasm function returns a pointer (offset) and length, then JS uses TextDecoder on a Uint8Array slice of memory.buffer. This manual memory management is a key Wasm concept that higher-level toolchains (Emscripten, wasm-bindgen) abstract away.
What are the four WebAssembly value types and when is each used?
i32 (32-bit integer) is the most common type, used for array indices, boolean values, and general-purpose integer math. i64 (64-bit integer) is for large integer values and timestamps. f32 (32-bit float) is for single-precision floating point, common in graphics. f64 (64-bit float) is for double-precision, used in scientific computation. Wasm is strictly typed, so you must use explicit conversion instructions (i32.wrap_i64, f64.convert_i32_s, etc.) to move between types.
What is the importObject and what can I pass through it?
The importObject is a JavaScript object whose structure mirrors the (import) declarations in the Wasm module. It passes host-provided functions, Memory instances, Table instances, and global values into Wasm. For example, if the module declares (import "env" "log" (func (param i32))), the importObject must have { env: { log: (x) => console.log(x) } }. This is the primary mechanism for Wasm to interact with the host environment (DOM, console, network, etc.).
What is WebAssembly.Table and why is call_indirect needed?
WebAssembly.Table stores function references that can be called indirectly at runtime. Since Wasm does not support direct function pointers for security reasons, Table provides a safe alternative. call_indirect indexes into the table to dispatch a call, enabling patterns like virtual method tables, callbacks, and dynamic dispatch. The table is typed (funcref) and bounds-checked at runtime, preventing out-of-bounds function calls that could compromise safety.
What is WASI and how does it differ from the browser WebAssembly API?
WASI (WebAssembly System Interface) is a standardized API that gives Wasm modules access to operating system resources like file systems, environment variables, clocks, and random number generators. While the browser Wasm API runs in a sandboxed web context, WASI enables running Wasm outside the browser using runtimes like Wasmtime or Wasmer. WASI follows a capability-based security model where modules only get access to explicitly granted resources, making it suitable for server-side, edge computing, and plugin systems.
What languages can compile to WebAssembly and what toolchains are used?
C and C++ use Emscripten (emcc) which provides a full POSIX-like environment. Rust uses wasm-pack with wasm-bindgen for seamless JS interop. Go has built-in Wasm support via GOOS=js GOARCH=wasm. AssemblyScript is a TypeScript-like language designed specifically for Wasm. Other languages with Wasm targets include Zig, Swift, Kotlin/Native, and C# via Blazor. The WAT text format shown in this reference is also hand-writable for low-level control and educational purposes.