# WebAssembly: an introduction

> WebAssembly lets browsers run compiled code from Rust, C, and C++. What WASM is, where it shines, and when web developers should care.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2026-08-14 | Updated: 2026-08-03 | Topics: [JavaScript](https://flaviocopes.com/tags/js/) | Canonical: https://flaviocopes.com/webassembly/

[WebAssembly](https://webassembly.org/) (WASM) is a low-level binary format the browser can run natively. It's not a language you write. Languages like Rust, C, C++, and Go compile *to* WebAssembly.

It's the second format browsers execute natively, after [JavaScript](https://flaviocopes.com/javascript/) showed up in the 90s. WASM is designed to be fast, portable, sandboxed, and open.

## WASM does not replace JavaScript

**WebAssembly is not meant to replace JavaScript.** It's a way to port programs written in other languages to the browser, or to power the heavy parts of an app.

JavaScript and WASM interoperate. You keep the flexibility of JS and add the performance of compiled code where you need it.

If you worked with JavaScript in the browser, you know it's great for UI, networking, and glue code. WASM takes over when raw CPU power matters.

## Where WASM shines

Many companies already use WebAssembly to make their web apps feel like desktop software.

**Figma** used WebAssembly to bring its C++ rendering engine to the browser. JavaScript still handles the surrounding web interface.

**Photoshop on the web** followed the same broad path. Adobe used Emscripten to bring parts of its existing C++ codebase to the browser instead of rewriting its image-processing engine in JavaScript.

Other common use cases:

- Video and image processing (filters, codecs, transcoding)
- Games and 3D rendering (Unity, Google Earth)
- Running SQLite in the browser via projects like sql.js

C and C++ teams typically use [Emscripten](https://emscripten.org/). Rust developers use **wasm-pack** and **wasm-bindgen** — still the most common path for new WASM modules today.

## Browser and Node.js support

WebAssembly is a [W3C standard](https://www.w3.org/wasm/). All modern browsers support it: Chrome, Firefox, Safari, Edge, and their mobile versions.

[Node.js](https://flaviocopes.com/nodejs/) has supported WASM since version 8. You can load `.wasm` files on the server the same way you do in the browser.

The spec keeps moving. WebAssembly 3.0 (September 2025) added garbage collection, exception handling, and 64-bit memory. That unlocks languages like Kotlin and Dart without shipping a custom GC inside every module.

## Safety

WASM runs in a sandboxed environment with the same security policies as JavaScript. The browser enforces same-origin and permissions rules.

You can't access the filesystem or the network from WASM directly. JavaScript stays the gatekeeper.

## A minimal example

You don't need Emscripten to try WASM. If someone hands you a compiled `.wasm` file, you can load it from JavaScript like this:

```js
const response = await fetch('module.wasm')
const { instance } = await WebAssembly.instantiateStreaming(response)

const result = instance.exports.add(2, 3)
console.log(result) // 5
```

`instantiateStreaming` compiles the WASM as it downloads. The server must send the file with the `application/wasm` content type, and a cross-origin file must allow the request with CORS.

If you cannot control the content type, load the bytes first:

```js
const response = await fetch('module.wasm')
const bytes = await response.arrayBuffer()
const { instance } = await WebAssembly.instantiate(bytes)
```

The exported `add` function is whatever the module compiled from Rust, C, or another language defined. Pass an imports object as the second argument when the module requires imports.

In practice, toolchains generate the glue code for you. But this is the core idea: fetch a binary, call its exports.

## Beyond the browser

WASM is not just a browser thing anymore. **WASI** (WebAssembly System Interface) lets the same compiled modules run on servers, at the edge, and in standalone runtimes like Wasmtime.

WASI 0.3 shipped in 2026 with native async support in the Component Model. It makes it easier for a runtime such as Wasmtime to compose components written in different languages.

[Cloudflare Workers](https://flaviocopes.com/cloudflare-workers/) can run WebAssembly too, but its WASI support is experimental and only implements some system calls. A module that targets WASI does not automatically run unchanged on every WASM host.

## Should you care?

For most web developers, the answer is: **you'll consume WASM without noticing.**

Libraries you npm install may already ship a `.wasm` file under the hood. Image editors, design tools, and game engines use it so you don't have to think about it.

Write WASM yourself when you have a CPU-heavy problem JavaScript can't solve fast enough — cryptography, parsing huge files, image filters, physics simulations. For everything else, stick with JavaScript.

That's WASM in a nutshell. A compiled binary format that makes the web faster without replacing the language you already know.
