What Is WebAssembly?
WebAssembly is defined by four core properties: a compact binary format, a stack-based virtual machine, deterministic execution, and sandboxed isolation. Understanding each one explains why Wasm has become the universal portable execution layer it is today.
The Binary Format
Section titled “The Binary Format”A .wasm file is a dense, type-annotated binary. Unlike JavaScript source, it requires no parsing beyond a single validation pass. The runtime can begin compiling it to native machine code almost immediately, which is why Wasm can achieve near-native performance even on first load.
The binary is also small. Function bodies, type signatures, imports, and exports are all encoded in a minimal section-based layout. A module that does real work can weigh less than a kilobyte.
The Stack VM Model
Section titled “The Stack VM Model”Wasm executes on a conceptual stack machine. Instructions push values onto an implicit operand stack and pop them off. There are no general-purpose registers you address by name — the VM manages them for you. This model is easy to validate (the type checker can walk the stack statically) and easy to compile to efficient register-based native code.
You will explore this in depth in Module 2 when you write WAT by hand. For now, just note that i32.const 42 pushes the 32-bit integer 42 onto the stack, and a function with (result i32) is expected to have exactly one i32 on the stack when it returns.
Deterministic Execution
Section titled “Deterministic Execution”Given the same .wasm bytes and the same inputs, a Wasm module produces identical results on every platform — x86, ARM, RISC-V, browser, server, edge. Floating-point behaviour is specified precisely (IEEE 754 with no implementation-defined rounding modes), and there is no undefined behaviour in the C sense. This property makes Wasm excellent for reproducible builds, cryptography, simulation, and any domain where byte-exact reproducibility matters.
Sandboxed by Default
Section titled “Sandboxed by Default”Wasm modules are hermetically isolated. A fresh module has no access to the filesystem, the network, the DOM, clocks, or any other OS resource. It exists in a linear memory region that only it and its host can address. It can only interact with the outside world through functions that the host explicitly imports into it. If the host does not provide a function, the module cannot call it — period.
This makes running untrusted third-party Wasm safe in a way that running arbitrary native code is not.
The .wasm / .wat Duality
Section titled “The .wasm / .wat Duality”Every .wasm binary has an exact textual equivalent called WAT (WebAssembly Text format). The two representations are 1:1: any .wasm can be decoded to .wat, and any valid .wat can be assembled back to the identical .wasm. You will write WAT throughout this course as the clearest way to understand what the binary actually contains.
Here is the simplest possible WAT module — a single exported function that returns the integer 42:
(module (func (export "answer") (result i32) i32.const 42))Reading this left-to-right: module is the top-level container; func defines a function; (export "answer") makes it callable from JavaScript as instance.exports.answer(); (result i32) declares it returns one 32-bit integer; and i32.const 42 pushes 42 onto the stack, which becomes the return value.
The runner below compiles that WAT string at runtime using WABT, instantiates the module, and calls answer(). You should see answer() = 42 in the output.