Expert · Real projects: CLI, web and WebAssembly · topic 46 of 50 · 30 min
Rust and WebAssembly
Explanation
What is WebAssembly?
Browsers originally ran only JavaScript. WebAssembly, supported by all major browsers since 2017, is a second language for the web: a compact, binary instruction format that runs in the same safe sandbox as JavaScript, but much closer to native machine speed for heavy calculations. You do not write Wasm by hand; you compile another language, such as Rust, C++ or Go, to it.
When Rust + Wasm makes sense
- Image and video processing in the browser: filters, resizing, background blur.
- PDF, spreadsheet or file-format work done on the user's device, so files never leave it (good for privacy).
- Games, simulations, charts with huge data sets.
- Sharing one tested Rust library between a server and a web front end.
It is not a good fit for ordinary button clicks and form handling: JavaScript is already fast enough there, and crossing between JS and Wasm has a small cost. Wasm also cannot touch the page (the DOM) directly; it goes through JavaScript glue.
The toolchain
rustup target add wasm32-unknown-unknown
cargo install wasm-pack[package]
name = "emi_calc"
version = "0.1.0"
edition = "2024"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn emi(principal: f64, yearly_rate: f64, months: u32) -> f64 {
if yearly_rate == 0.0 {
return principal / months as f64;
}
let r = yearly_rate / 12.0 / 100.0;
let f = (1.0 + r).powi(months as i32);
principal * r * f / (f - 1.0)
}wasm-pack build --target web<script type="module">
import init, { emi } from './pkg/emi_calc.js';
await init(); // load and start the Wasm module
console.log(emi(500000, 9, 60).toFixed(2)); // 10379.18
</script>Size and debugging tips
- Build in release mode (wasm-pack does by default) and avoid heavy dependencies; every crate adds bytes users must download.
- Pass big data as bytes (Vec<u8> / Uint8Array) in one call, rather than calling back and forth thousands of times.
- Add the console_error_panic_hook crate during development so Rust panics show readable messages in the browser console.
Wasm outside the browser
Wasm also runs outside browsers, in runtimes such as Wasmtime and in some edge-computing and plugin platforms. WASI (the WebAssembly System Interface) gives such programs controlled access to files, clocks and networks. Rust supports it with dedicated targets; it is a young, fast-moving area, so read the current documentation before choosing it.
Common mistakes
- Forgetting crate-type = ["cdylib"]: no usable .wasm is produced.
- Opening the HTML file directly from disk. Use a local server (for example python -m http.server).
- Expecting Wasm to speed up DOM-heavy code. It helps with computation, not with page updates.
- Shipping a debug build: much larger and slower.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Rust and WebAssembly · 1/6
WebAssembly is a fast binary format that runs in the browser next to JavaScript.
Prefer a video by a teacher? Find free videos on “rust webassembly wasm-bindgen wasm-pack tutorial” on YouTube ↗
In real life: Compressing photos on the user's phone
A government-form helper website lets users upload passport photos that must be under 50 KB. Instead of uploading the original 4 MB photo to a server, the site compresses it in the browser with a Rust library compiled to Wasm. It is fast, works even on a slow mobile connection, and the user's photo never leaves their phone until they submit it.
use wasm_bindgen::prelude::*;
/// Turns RGBA pixels to greyscale in place; called from JavaScript with a Uint8Array.
#[wasm_bindgen]
pub fn greyscale(pixels: &mut [u8]) {
for px in pixels.chunks_exact_mut(4) {
let y = (0.299 * px[0] as f32 + 0.587 * px[1] as f32 + 0.114 * px[2] as f32) as u8;
px[0] = y;
px[1] = y;
px[2] = y;
}
}Practice (0/3 done)
Which job is the best fit for Rust compiled to WebAssembly?
Which target compiles Rust to WebAssembly for the browser?
Create the emi_calc crate from this topic, build it with wasm-pack build --target web, and write an index.html with three inputs (amount, rate, months) and a button that shows the EMI using your Wasm function. Serve it locally and test it on your phone on the same Wi-Fi.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Serde and JSONReal projects: CLI, web and WebAssembly · same module
- Building a CLI toolReal projects: CLI, web and WebAssembly · same module
- Flutter on the web and desktopFlutter and Dart · Publishing to the stores and the web
- Where Rust is used and the job marketRust careers and interviews
- Portfolio, open source and a learning planRust careers and interviews
- Node.js: JavaScript on the serverBackend Development · Node.js and Express
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What is WebAssembly?
Answer: A compact binary format browsers run at near-native speed
Wasm is a compilation target supported by all major browsers.
What does wasm-bindgen do?
Answer: Generates glue so JavaScript and Rust can call each other
It handles type conversion between JS and Wasm.
Can Wasm change the page (DOM) directly?
Answer: No, it goes through JavaScript glue
DOM access goes through JS bindings.
Which crate-type is needed to build a Wasm library for JavaScript?
Answer: cdylib
cdylib produces a dynamic library that wasm-bindgen can wrap.
What does flutter build web --wasm produce?Related
Answer: A WebAssembly build of the web app
Faster in supporting browsers.
How does Rust free memory?Related
Answer: Through ownership: a value is freed when its owner goes out of scope
Ownership rules make freeing automatic and predictable, and the compiler checks them.
Which area is a well-known public use of Rust?Related
Answer: Parts of the Linux kernel and cloud infrastructure
Rust is used in kernels, cloud services and tools.
How often does Rust release a new stable version?Related
Answer: Every 6 weeks
Stable releases come every six weeks.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- This is the last topic of “Real projects: CLI, web and WebAssembly”. The module exam comes next.
- Module 11 exam: Real projects · 13 questions · 25 min, without help. 4 topics of this module still to finish first.
- Then the next module, Rust careers and interviews. 50 topics left in the course before the final exam.