The JavaScript WebAssembly API

10.1 Loading and Instantiating

// Preferred: streaming compile + instantiate (compiles while downloading)
const { module, instance } = await WebAssembly.instantiateStreaming(fetch("app.wasm"), imports);

// From bytes (Node, or when you already have an ArrayBuffer)
const bytes = await (await fetch("app.wasm")).arrayBuffer();
const result = await WebAssembly.instantiate(bytes, imports);

// Compile once, instantiate many times (e.g., in workers)
const mod = await WebAssembly.compileStreaming(fetch("app.wasm"));
const inst1 = await WebAssembly.instantiate(mod, imports);
const inst2 = new WebAssembly.Instance(mod, imports);   // synchronous (avoid for large modules on the main thread)

WebAssembly.validate(bytes);                       // true/false
WebAssembly.Module.exports(mod);                   // [{ name, kind }]
WebAssembly.Module.imports(mod);                   // [{ module, name, kind }]
WebAssembly.Module.customSections(mod, "name");

10.2 API Objects

Compiled, stateless code (can be posted to workers, cached in IndexedDB in some browsers) A module + state. .exports.

new WebAssembly.Memory({ initial, maximum, shared }), .buffer, .grow(n)

new WebAssembly.Table({ element: "anyfunc", initial }), .get/.set/.grow

{ value: "i32" | "i64" | "f32" | "f64" | "externref" | "anyfunc", mutable }, .value

WebAssembly.Tag / WebAssembly.Exception Exception handling across JS/Wasm (Module 24)

CompileError, LinkError (bad imports), RuntimeError (traps)

10.3 Sharing Memory with JS

const memory = new WebAssembly.Memory({ initial: 1, maximum: 100 });
const { instance } = await WebAssembly.instantiateStreaming(fetch("mem.wasm"), { env: { memory } });

let bytes = new Uint8Array(memory.buffer);
bytes.set([1, 2, 3, 4], 0);
console.log(instance.exports.sum_bytes(0, 4)); // 10

memory.grow(1);
// ⚠️ After growth, old views are DETACHED: recreate them
bytes = new Uint8Array(memory.buffer);

10.4 Error Handling

try {
  instance.exports.divide(1, 0);
} catch (e) {
  if (e instanceof WebAssembly.RuntimeError) console.error("Trap:", e.message); // "divide by zero"
}

10.5 ES Module Integration

Bundlers: Vite (?init, vite-plugin-wasm), webpack 5 (experiments.asyncWebAssembly), Rollup/esbuild plugins.

// Proposal: import Wasm directly as an ES module (supported in some runtimes/bundlers; "source phase imports" in progress)
import { add } from "./add.wasm";
import source addModule from "./add.wasm";   // source phase import (TC39 proposal)