WebAssembly (WASM)
Compile Rust, C++, or Go to WebAssembly for near-native browser performance. Build WASM modules with wasm-pack and integrate with JavaScript.
WebAssembly (WASM) enables near-native performance in the browser by running compiled code from Rust, C++, Go, or AssemblyScript. It's used for compute-heavy workloads: video encoding, image processing, cryptography, game engines, and scientific computing.
Use WASM for specific performance-critical inner loops, not for entire applications. Rust + wasm-pack is the best developer experience. Keep JS↔WASM boundary calls minimal (crossing the boundary has overhead). Profile before rewriting in WASM.
Workflow
- Compile Rust to WASM with wasm-packwasm-pack automates the Rust → WASM → npm package pipeline, producing optimized modules with JS glue code.
- Integrate WASM into JavaScriptThe generated JS glue handles memory management and type conversion between JS and WASM.
- Work with complex types and shared memoryPassing objects and arrays between JS and WASM requires explicit memory management.
- Optimize WASM bundle sizeWASM modules can be large; optimization is critical for web performance.
- Use Web Workers for background computationWASM running in the main thread blocks UI; Web Workers enable truly parallel computation.
Output Format
Rust library with wasm-bindgen, wasm-pack build producing npm package, integrated into web bundler, loaded asynchronously, computation in Web Worker.
Examples
Rust WASM: `#[wasm_bindgen] pub fn hash_password(password: &str) -> String { use sha2::{Sha256, Digest}; format!("{:x}", Sha256::digest(password.as_bytes())) }`JS usage: `import init, { hash_password } from "./pkg/crypto_wasm"; await init(); const hash = hash_password("secret123");`Image processing: `#[wasm_bindgen] pub fn grayscale(data: &mut [u8]) { for i in (0..data.len()).step_by(4) { let gray = (data[i] as u16 * 299 + data[i+1] as u16 * 587 + data[i+2] as u16 * 114) / 1000; data[i] = gray as u8; data[i+1] = gray as u8; data[i+2] = gray as u8; } }`Edge Cases & Gotchas
- WASM startup time: initialization is async and can take 50-200ms for large modules; show loading state and pre-load WASM during idle time with `<link rel="modulepreload">`
- Debugging: WASM debugging in Chrome DevTools requires DWARF debug info; enable with `wasm-pack build --debug` in development
- Memory leaks: Rust WASM objects exposed to JS must be explicitly freed: `const obj = wasmModule.MyStruct.new(); obj.process(); obj.free();` - forget to free and memory leaks
When to Break These Rules
- For simple data transformation or string processing, JavaScript (especially with V8's JIT) is fast enough and infinitely simpler to debug than cross-language WASM boundaries.
Reference Files
Rust and WebAssembly book: https://rustwasm.github.io/docs/book/wasm-pack: https://rustwasm.github.io/wasm-pack/MDN WebAssembly: https://developer.mozilla.org/en-US/docs/WebAssemblywasm-bindgen: https://rustwasm.github.io/docs/wasm-bindgen/