Workshop: Production-ready WebAssembly with Rust
The goal of this workshop is allowing experienced Rust engineers to develop WebAssembly modules that can be seamlessly integrated with Node.js and TypeScript codebases. No previous knowledge of WebAssembly is required.
We will be coding through a series of tutorials and test-driven exercises covering topics that every WebAssembly developer likely encounters in production settings:
wasm_bindgen, its uses, limitations, and alternatives
- error management and panic handling
Along the way, we'll point out some edge cases that will hopefully help you avoid hours of head-scratching and debugging sessions 😄.
We'll also hint at ways you can overcome WebAssembly's own limitations, proving that you can actually run I/O logic without needing WASI.
Finally, we'll demonstrate how to port a moderately complex Rust library to WebAssembly, applying the concepts learnt during the workshop.
Before diving into the workshop, let's make sure you have the following tools installed in your system:
- A bash-compatible shell (if you use Windows you can install bash or use Docker, as described below)
- Rust (tested on v
- Node.js (tested on v
pnpm(tested on v
npm install -g pnpm
- A text editor of your choice (I recommend Visual Studio Code)
Optionally, you can also install the Wasm binary tools from
bynarien. They are not strictly required for the workshop, but they can be useful to inspect the generated WebAssembly modules. If you use Docker, you'll find these tools (e.g.,
wasm-opt) already installed.
Clone the repository and run
./install.sh to get all the necessary dependencies. This workshop is divided into chapters, containing a mixture of lessons and exercises.
The first chapter is
Each chapter focuses on a specific concept about WebAssembly development, and provides some examples and exercises to familiarize with that concept. For each chapter, you will need to complete some Rust code.
To test the exercises, open two terminal tabs side-by-side:
./watch.sh in each tab, followed by the chapter number. For instance, for the first chapter, if you run
./watch.sh 2 in each tab,
the Rust code will silently be re-compiled to WebAssembly for you via
cargo watch, and tested on Node.js via
The Rust source code in
./rust uses Cargo workspaces. This enables sharing dependencies across the exercise crates for each chapter via the
[workspace.dependencies] attribute in
./rust/Cargo.toml: rather than having to add a specific version of a dependency in an exercise crate, we can refer to the workspace version instead.
# Cargo.toml in an exercise crate
wasm-bindgen.workspace = true # <- wasm-bindgen = "0.2.88"
Should run into any issue with the repository and the assumed level of knowledge, please raise your hand and ping us, so we can sort this through together 🪄. Enjoy!
If you prefer to keep your environment clean and use Docker, you have two choices:
- If you use VSCode, you can re-open this repository in a DevContainer by running the
Dev Containers: Reopen in Containercommand (you can open the command palette via
- Otherwise, you can spin up a workable environment in your terminal via:
docker compose run --build --rm -it workspace
- ➡️ Demo
This is a work in progress, so stay tuned for more chapters about:
async / awaitsupport
- online WebAssembly debugging on Chrome Dev Tools with source maps and breakpoints
WASIsupport on Node.js
- Publish WebAssembly modules on
- and more!
Licensed under MIT License. © Alberto Schiabel.