Skip to content

The WAT Text Format

WebAssembly exists in two forms: a dense binary format (.wasm) that browsers execute, and a human-readable text format called WAT — the WebAssembly Text format. The two are 1:1 equivalent; every construct in WAT has an exact binary counterpart.

You will almost never write WAT in production. Compilers for C, Rust, Go, and other languages produce .wasm directly. But reading and writing WAT by hand is the fastest way to build an accurate mental model of how WebAssembly actually works.

The pipeline from source text to a callable JS function has four steps.

flowchart LR
  A["WAT source\n(text string)"] --> B["compileWat()\n→ Uint8Array"]
  B --> C["WebAssembly.instantiate()\n→ instance"]
  C --> D["instance.exports\n(exported functions)"]
  D --> E["JS call\nconsole.log(add(2,3))"]
WAT to running function
  1. WAT source — a text string you author (or a .wat file on disk).
  2. Compile to bytes — the compileWat() helper in this sandbox calls the WebAssembly Binary Toolkit (WABT) and returns a Uint8Array of .wasm bytes.
  3. InstantiateWebAssembly.instantiate(bytes, {}) parses and JIT-compiles the bytes, returning a WebAssembly.Instance.
  4. Callinstance.exports.add(2, 3) invokes the exported function from JavaScript.

Here is the smallest useful WAT program — an add function that takes two 32-bit integers and returns their sum:

(module
(func (export "add") (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add))

A few things to notice:

  • The entire program is wrapped in (module ...).
  • (func ...) declares a function. The (export "add") attribute makes it callable from JavaScript.
  • (param $a i32) and (param $b i32) declare two named parameters of type i32 (32-bit integer).
  • (result i32) declares the return type.
  • The body is a sequence of stack instructions. local.get $a pushes the value of $a, local.get $b pushes $b, and i32.add pops both and pushes their sum.

WebAssembly uses a stack machine model. Instructions pop their inputs from the stack and push results back. At the end of a function the single value left on the stack is the return value.

The editor below contains the same add example wired up as runnable JavaScript. Click Run to compile the WAT and call the function.

WebAssembly
What does WAT stand for?
What does the compileWat() helper return?
In production code, WAT is typically...