Exploring WebAssembly (WASM)
Getting Started with WebAssembly
Running WebAssembly in the Browser
After compiling our temperature-converter to a WebAssembly module, you can load and execute it directly in the browser using JavaScript as a bridge. In this guide, we’ll cover:
- Fetching and instantiating a
.wasm
module - Sharing memory between JavaScript and WebAssembly
- Building a minimal HTML example
- Understanding how browsers run WebAssembly
1. Loading and Instantiating WASM with JavaScript
The easiest way to download and compile a .wasm
module in one step is with WebAssembly.instantiateStreaming
. Modern browsers support this API, but if you need to support older environments, a two-step fallback is required.
Approach | Browser Support | Behavior |
---|---|---|
instantiateStreaming | Modern browsers | Streams fetch → compile → instantiate |
fetch → instantiate fallback | Legacy browsers | Downloads binary → compiles → instantiates |
Ensure correct MIME type
Your server must serve .wasm
files with application/wasm
. Otherwise, streaming instantiation will fail.
Streaming Instantiation
const importObject = {};
WebAssembly.instantiateStreaming(
fetch('converter.wasm'),
importObject
).then(({ instance }) => {
const result = instance.exports.celsius_to_fahrenheit(25);
console.log(`25°C is ${result}°F`);
}).catch(err => {
console.error('WASM streaming failed:', err);
});
Fallback for Older Browsers
fetch('converter.wasm')
.then(resp => resp.arrayBuffer())
.then(buffer =>
WebAssembly.instantiate(buffer, importObject)
)
.then(({ instance }) => {
const result = instance.exports.celsius_to_fahrenheit(25);
console.log(`25°C is ${result}°F`);
})
.catch(err => {
console.error('WASM instantiation failed:', err);
});
Both methods produce an instance
whose exports
object contains your converter function.
2. JavaScript ↔ WebAssembly Memory Sharing
JavaScript and WebAssembly exchange data through linear memory—a shared ArrayBuffer
where both sides can read and write.
WebAssembly’s linear memory is simply a contiguous array of bytes:
When JavaScript needs to pass a value (like the number 25) to WebAssembly:
- JS writes the value into the shared buffer.
- WASM reads it, performs the conversion, and writes the result back.
- JS reads the converted value (e.g., 77) from the same buffer.
Note
By default, linear memory grows in 64 KB pages. You can configure initial and maximum sizes in your toolchain.
3. A Simple HTML Example
Combine everything into a minimal web page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Temperature Converter</title>
</head>
<body>
<label>
Enter Celsius:
<input id="celsiusInput" type="number" />
</label>
<button onclick="convert()">Convert</button>
<div id="output"></div>
<script src="script.js"></script>
</body>
</html>
In script.js, handle both instantiation paths and wire up the convert()
function:
const importObject = {};
let wasmInstance = null;
// Try streaming instantiation
WebAssembly.instantiateStreaming(fetch('converter.wasm'), importObject)
.then(({ instance }) => {
wasmInstance = instance;
})
.catch(() => {
// Fallback
return fetch('converter.wasm')
.then(res => res.arrayBuffer())
.then(buffer => WebAssembly.instantiate(buffer, importObject))
.then(({ instance }) => {
wasmInstance = instance;
});
});
function convert() {
const c = parseFloat(
document.getElementById('celsiusInput').value
);
const f = wasmInstance.exports.celsius_to_fahrenheit(c);
document.getElementById('output').innerText =
`That's ${f.toFixed(2)}°F!`;
}
Open the page in your browser, input a Celsius value, and click Convert—the result comes straight from WebAssembly.
4. How Browsers Run WebAssembly
Browsers like Chrome (V8), Firefox (SpiderMonkey), Safari, and Edge integrate WebAssembly support directly into their JavaScript engines. They treat .wasm
as bytecode, decoding and compiling it alongside JS.
When a .wasm
module loads, the engine:
- Parses the binary format.
- Compiles it to native machine code.
- Links it with the JS context (including linear memory).
This approach allows WebAssembly to leverage the same JIT optimizations, garbage collection, and security sandbox as JavaScript.
Engine | JavaScript Engine | WebAssembly Engine |
---|---|---|
Chrome | V8 | Integrated WAsm |
Firefox | SpiderMonkey | Integrated WAsm |
Safari | JavaScriptCore | Integrated WAsm |
Edge | Chakra/Sparta | Integrated WAsm |
By understanding these internals, you can harness WebAssembly to accelerate compute-intensive tasks and integrate seamlessly with your existing JavaScript code.
Links and References
Watch Video
Watch video content