Skip to content

Compile and Instantiate

Loading a WebAssembly module from JavaScript is a two-phase process: compile the bytes into a validated module artifact, then instantiate that module to get a running instance with callable exports. The browser’s WebAssembly global exposes dedicated APIs for both phases — and a convenient shortcut that does both at once.

WebAssembly.compile(bufferSource) takes any BufferSource (a Uint8Array, ArrayBuffer, or similar) and returns a Promise<WebAssembly.Module>. The resulting Module is a compiled, validated artifact — the browser has parsed and optimised the bytes, but nothing has been executed yet.

const response = await fetch('module.wasm');
const bytes = await response.arrayBuffer();
const module = await WebAssembly.compile(bytes);
// `module` can be cached, cloned, or passed to a Worker via postMessage

Because the Module object is serialisable, it can be stored in IndexedDB or sent to another thread with postMessage — you pay the compilation cost once and reuse the result.

WebAssembly.instantiate() has two overloads:

// Overload 1 — pass raw bytes: compiles AND instantiates in one call
const { module, instance } = await WebAssembly.instantiate(bytes, importObject);
// Overload 2 — pass an already-compiled Module: instantiates only
const instance = await WebAssembly.instantiate(module, importObject);
// Note: this overload returns a WebAssembly.Instance directly, not {module, instance}

The first overload is the most common starting point. The second is useful when you want to instantiate the same compiled module multiple times — for example, to create isolated sandboxes that share no state.

After instantiation, instance.exports is a plain JavaScript object whose keys are the names declared in the Wasm module’s export section. Every exported function, memory, global, or table appears as a property. Exported functions behave like regular JS functions — you call them, pass JS numbers, and receive JS numbers back.

const { instance } = await WebAssembly.instantiate(bytes, {});
const { square, cube } = instance.exports;
console.log(square(5)); // 25
console.log(cube(3)); // 27

The WAT module that defines those exports looks like this:

(module
(func (export "square") (param $n i32) (result i32)
local.get $n
local.get $n
i32.mul)
(func (export "cube") (param $n i32) (result i32)
local.get $n
local.get $n
i32.mul
local.get $n
i32.mul))

The runner below compiles the module, instantiates it, and calls both exports.

WebAssembly
What does WebAssembly.instantiate(bytes, {}) return?
Which property of the instantiation result holds callable exported functions?
Can a compiled WebAssembly.Module be re-instantiated multiple times?