WebAssembly (Wasm) enables near-native performance in web browsers and increasingly on servers through WASI. This guide covers building Wasm modules from Rust, Go, and AssemblyScript, deploying them in browsers and server-side runtimes, and understanding when Wasm is the right choice.
WebAssembly with Rust
# Install wasm-pack
cargo install wasm-pack
# Create a library project
cargo new --lib wasm-app
cd wasm-app
# Cargo.toml
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
serde = { version = "1", features = ["derive"] }
serde-wasm-bindgen = "0.6"
web-sys = { version = "0.3", features = ["console"] }
// src/lib.rs
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u64 {
match n {
0 => 0,
1 => 1,
_ => {
let mut a: u64 = 0;
let mut b: u64 = 1;
for _ in 2..=n {
let temp = a + b;
a = b;
b = temp;
}
b
}
}
}
#[wasm_bindgen]
pub fn process_data(data: &[u8]) -> Vec {
// CPU-intensive data processing at native speed
data.iter().map(|&b| b.wrapping_mul(2)).collect()
}
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Hello, {}! From WebAssembly.", name)
}
// Build: wasm-pack build --target web
Using Wasm in the Browser
<!DOCTYPE html>
<html>
<head><title>Wasm App</title></head>
<body>
<script type="module">
import init, { fibonacci, greet } from "./pkg/wasm_app.js";
async function main() {
await init();
// Call Wasm functions
console.log(greet("World"));
console.log(`fib(40) = ${fibonacci(40)}`);
// Benchmark: Wasm vs JavaScript
const jsStart = performance.now();
jsFibonacci(40);
const jsTime = performance.now() - jsStart;
const wasmStart = performance.now();
fibonacci(40);
const wasmTime = performance.now() - wasmStart;
console.log(`JS: ${jsTime}ms, Wasm: ${wasmTime}ms`);
}
function jsFibonacci(n) {
if (n