Learn WebAssembly: The Best Books, in Order
This curriculum takes an intermediate developer from a solid understanding of WebAssembly's core concepts all the way to production-grade, multi-language Wasm development. Each stage builds on the last — starting with the binary format and browser runtime, moving through compiling C/C++ and Rust to Wasm, and finishing with advanced component models and real-world system design.
WebAssembly Foundations
IntermediateUnderstand what WebAssembly is, how the binary format and stack machine work, and how to run Wasm in the browser with JavaScript interop.
▸ Study plan for this stage
Pace: 6–8 weeks, ~25–30 pages/day (mix of both books, alternating focus)
- What WebAssembly is: a portable binary instruction format and virtual machine designed for safe, fast execution in browsers and beyond
- The WebAssembly stack machine model: how instructions operate on a value stack and why this design enables efficient compilation
- Binary format fundamentals: module structure, sections (type, function, memory, data), and how bytecode is organized and parsed
- Linear memory model: how Wasm manages a flat byte array, memory growth, and interaction with JavaScript
- JavaScript interoperability: importing/exporting functions, passing data between JS and Wasm, and the WebAssembly API (instantiate, Memory, Table)
- Rust-to-Wasm compilation pipeline: how Rust code compiles to Wasm, tooling (wasm-pack, cargo), and optimization considerations
- Performance characteristics: why Wasm is faster than JavaScript for compute-heavy tasks, and when to use it strategically
- What problem does WebAssembly solve, and why is it better than shipping native binaries or relying solely on JavaScript?
- Explain how the WebAssembly stack machine works: how are operands and results managed during instruction execution?
- What are the main sections in a WebAssembly module, and what role does each section play?
- How does linear memory work in WebAssembly, and how do you read/write data from JavaScript?
- Describe the process of exporting a Rust function to WebAssembly and calling it from JavaScript. What does wasm-pack do?
- What are the performance trade-offs between WebAssembly and JavaScript, and when should you choose Wasm for a project?
- Read and annotate the WebAssembly binary format section in Sletten's book; decode a simple .wasm file by hand to understand module structure
- Write a minimal Wasm module in WebAssembly Text (WAT) format that adds two numbers, then instantiate and call it from JavaScript
- Create a Rust project using cargo and wasm-pack that exports a simple function (e.g., fibonacci or string manipulation); call it from a web page
- Build a memory-sharing example: allocate a buffer in Wasm, write data from JavaScript, and have Wasm read and process it
- Implement a performance comparison: write a compute-intensive function (e.g., prime sieve) in both JavaScript and Rust-to-Wasm, measure execution time
- Explore the WebAssembly API: write code that uses WebAssembly.Memory and WebAssembly.Table to understand dynamic linking and memory management
Next up: This stage establishes the core mental model of how Wasm works at the binary and runtime level, preparing you to explore advanced topics like multi-threading, SIMD, and production optimization patterns in the next stage.

The single most comprehensive and up-to-date canonical reference for WebAssembly — covers the text format (WAT), binary format, browser APIs, and multi-language compilation in one place. Start here to build a complete mental model.

Read second to immediately ground abstract Wasm concepts in a practical, strongly-typed language; Hoffman walks through the Wasm execution model while building real browser and non-browser modules in Rust.
Compiling C and C++ to WebAssembly
IntermediateUse Emscripten to compile existing C and C++ codebases to Wasm, manage memory manually, and integrate native libraries into web applications.
▸ Study plan for this stage
Pace: 4–5 weeks, ~25–30 pages/day, focusing on Chapters 7–10 of "WebAssembly in Action" (Emscripten toolchain, C/C++ compilation, memory management, and library integration)
- Emscripten toolchain setup and configuration for C/C++ to Wasm compilation
- Understanding the compilation pipeline: C/C++ source → LLVM → Wasm bytecode
- Manual memory management in Wasm: heap allocation, pointers, and data layout
- JavaScript-Wasm interop: calling C/C++ functions from JS and passing data across the boundary
- Binding native C/C++ libraries to JavaScript using Emscripten's embind and manual FFI techniques
- Debugging compiled Wasm code and profiling performance bottlenecks
- Handling file I/O, threading, and platform-specific code in Wasm environments
- How does Emscripten transform C/C++ code into WebAssembly, and what role does LLVM play in this process?
- What are the key differences between manual memory management in C/C++ and how it translates to Wasm linear memory?
- How do you expose C/C++ functions to JavaScript, and what are the trade-offs between embind and manual binding?
- What strategies can you use to pass complex data structures (arrays, structs, objects) between JavaScript and Wasm?
- How do you integrate an existing C/C++ library into a web application using Emscripten?
- What debugging and profiling tools are available for Wasm compiled from C/C++, and how do you use them?
- Set up Emscripten on your machine and compile a simple C program (e.g., factorial, Fibonacci) to Wasm; call it from JavaScript and verify output
- Write a C program that allocates memory on the heap, perform operations, and free it; expose memory access functions to JavaScript and manipulate data from the web
- Create a C++ class with methods and use embind to expose it to JavaScript; instantiate and call methods from a web page
- Port an existing open-source C library (e.g., zlib, libpng) to Wasm using Emscripten; create a JavaScript wrapper and test with real data
- Build a performance-critical function in C (e.g., image processing, cryptography) and benchmark it against a JavaScript equivalent; analyze the performance gains
- Debug a compiled Wasm module using browser DevTools and source maps; set breakpoints and inspect memory state
Next up: This stage equips you with the practical skills to bring existing C/C++ ecosystems into the web, setting the stage for advanced topics like optimizing Wasm performance, managing complex multi-threaded applications, and deploying production systems that leverage both native and web technologies.

Gallant's hands-on approach focuses heavily on C/C++ compiled via Emscripten, covering dynamic linking, threading, and SIMD — exactly the toolchain knowledge needed to port native code to the browser.
Rust and WebAssembly in Depth
IntermediateBuild high-performance browser applications and npm packages using Rust and wasm-bindgen, and understand the Rust/Wasm toolchain end-to-end.
▸ Study plan for this stage
Pace: 8–10 weeks, ~40–50 pages/day (mix of reading and hands-on practice)
- Rust's ownership system, borrowing, and lifetime rules as they apply to memory-safe systems programming
- Low-level systems concepts: memory layout, pointers, unsafe code, and FFI fundamentals from 'Rust in Action'
- Advanced trait design, generics, and type system patterns for building reusable abstractions
- Concurrency primitives (threads, async/await, channels) and their performance implications in WebAssembly contexts
- The Rust compiler's optimization capabilities and how to profile and benchmark Rust code
- Building and packaging Rust libraries for WebAssembly using wasm-bindgen and npm tooling
- Interop patterns: calling Rust from JavaScript and vice versa, managing memory across the boundary
- Performance debugging and optimization techniques specific to browser environments
- How do Rust's ownership and borrowing rules prevent memory safety issues, and why are they critical for WebAssembly?
- What is the difference between safe and unsafe Rust, and when is unsafe code necessary in wasm-bindgen projects?
- How do lifetimes work, and what role do they play in preventing dangling pointers in WebAssembly modules?
- What are the key performance considerations when designing Rust code that will run in the browser, and how do you measure them?
- How does wasm-bindgen facilitate JavaScript-Rust interoperability, and what are the costs of crossing the FFI boundary?
- What concurrency models are practical in WebAssembly, and how do they differ from traditional multi-threaded Rust?
- How do you structure a Rust project for npm distribution, and what does the build and packaging pipeline look like?
- Work through 'Rust in Action' hands-on projects (e.g., building a file I/O utility, implementing a simple network client) to internalize ownership and memory safety patterns
- Implement a non-trivial data structure (e.g., a custom HashMap or graph) using advanced trait bounds and generics from 'Rust for Rustaceans', then refactor it for WebAssembly
- Create a wasm-bindgen project that wraps a performance-critical algorithm (e.g., image processing, sorting, or cryptography) and expose it to JavaScript via npm
- Write both safe and unsafe Rust code in a wasm module; document why unsafe is necessary and verify memory safety with tools like Miri
- Build a small async/concurrent Rust application (e.g., a task scheduler or event processor) and adapt it to run in a browser environment using wasm-bindgen
- Profile a Rust WebAssembly module using browser DevTools and wasm-opt; identify bottlenecks and optimize hot paths
- Publish a Rust library to npm as a WebAssembly package, complete with TypeScript bindings and documentation
Next up: This stage equips you with deep Rust expertise and hands-on experience building performant wasm modules, preparing you to tackle advanced topics like optimizing wasm bytecode, integrating with complex JavaScript frameworks, and scaling to production-grade applications.

Before pushing Rust-to-Wasm to its limits, this book deepens your Rust systems knowledge — memory, concurrency, and unsafe code — so the Wasm compilation targets make complete sense.

Elevates your Rust to the level needed for writing zero-cost, production-quality Wasm libraries; covers advanced traits, lifetimes, and FFI patterns that appear constantly in wasm-bindgen and wasm-pack workflows.
Beyond the Browser — WASI and the Component Model
ExpertRun WebAssembly outside the browser using WASI, understand the emerging component model, and design portable, sandboxed Wasm systems.
▸ Study plan for this stage
Pace: 4–5 weeks, ~25–30 pages/day (focusing on Chapters 8–12 covering WASI, system integration, and component design)
- WASI (WebAssembly System Interface) as a standardized abstraction layer for OS capabilities
- Sandboxing and capability-based security model in WebAssembly
- System calls and file I/O through WASI APIs
- The Component Model as a solution for composability and interoperability across languages
- Portable module design: writing Wasm that runs identically across different runtimes (Wasmtime, Wasmer, etc.)
- Linking and dependency management in modular Wasm systems
- Real-world deployment patterns: serverless, edge computing, and embedded systems
- How does WASI enable WebAssembly to safely access system resources like files and environment variables?
- What is the capability-based security model, and how does it differ from traditional OS permission systems?
- Explain the Component Model and why it matters for building large-scale, multi-language Wasm systems.
- How would you design a portable WebAssembly module that runs identically on Wasmtime, Wasmer, and other runtimes?
- What are the key differences between browser-based Wasm and WASI-based Wasm in terms of APIs and constraints?
- How does the Component Model address the problem of language interoperability in WebAssembly?
- Build a WASI-enabled Wasm module that reads from a file, processes its contents, and writes output to another file using Wasmtime.
- Write a simple command-line tool in Rust/C that compiles to Wasm with WASI, then run it outside the browser using a WASI runtime.
- Create a multi-module Wasm system where one module calls functions from another, exploring linking and module composition.
- Design and implement a sandboxed plugin system using WebAssembly: host application loads and executes untrusted Wasm plugins with restricted capabilities.
- Experiment with the Component Model by defining a component interface (WIT) and implementing it in multiple languages, then composing them together.
- Deploy a WASI-based Wasm application to an edge computing platform (e.g., Fastly Compute, Cloudflare Workers) or serverless environment and measure cold-start performance.
Next up: This stage establishes WebAssembly as a portable, secure runtime for systems programming and distributed computing, preparing you to explore advanced topics like performance optimization, formal verification, or specialized domains (AI/ML, cryptography) where Wasm is becoming increasingly critical.

Battagline goes deep on the WAT text format, hand-writing Wasm modules, and optimizing at the instruction level — essential for understanding what compilers emit and how to debug or tune Wasm output.
Discussion
Keep reading
Paths that share books, cover the same subject, or open a related topic.