WAT Text Format Basics
WAT (WebAssembly Text Format) is the human-readable, textual counterpart to the .wasm binary format; tools like wat2wasm and wasm2wat translate losslessly between the two, so WAT is mainly used for debugging, teaching, and hand-writing small examples rather than for production authoring. Every WAT file is built from S-expressions — parenthesized, prefix-notation lists like (i32.add (i32.const 1) (i32.const 2)) — mirroring the tree structure the binary format encodes far more compactly.
Cricket analogy: Like a match's detailed written commentary transcript that maps one-to-one onto the compact scorecard numbers, WAT is the readable transcript form of the terse binary .wasm file, translatable losslessly in both directions.
S-Expression Syntax
Every construct in WAT — modules, functions, instructions, types — is written as a parenthesized list beginning with a keyword: (module ...) wraps the whole file, (func ...) declares a function, and instructions can be written either in a flat, stack-oriented 'linear' style (local.get $a followed by local.get $b followed by i32.add) or nested as folded S-expressions like (i32.add (local.get $a) (local.get $b)), which the WAT parser desugars into exactly the same instruction sequence.
Cricket analogy: Like describing a dismissal either step by step in commentary ('bowled to Kohli, edged, caught by keeper') or nested as one summary phrase ('caught behind off an edge'), WAT's linear and folded instruction styles compile to the same result.
Functions, Locals, and Exports
A function is declared with (func $name (param $x i32) (result i32) ...), where params and locals are referenced either by the $name given or by their positional index; the (export "name" (func $name)) form exposes a function under a public string name so the host (JavaScript, WASI, or another module) can call it by that name via WebAssembly.Instance.exports.
Cricket analogy: Like a fielding position that can be referred to either by the player's name or by its fixed numeric slot in the field diagram, a WAT local can be referenced by its $name or its positional index.
(module
(func $mul (param $a i32) (param $b i32) (result i32)
(i32.mul (local.get $a) (local.get $b)))
(export "mul" (func $mul)))Memory and Data Sections
The (memory 1) declaration allocates one 64 KiB page of linear memory for the module (optionally with a max page count), and (data (i32.const 0) "Hi") pre-initializes bytes at a given offset when the module is instantiated — this is exactly how a compiled program embeds string literals and constant tables into the module so they exist in linear memory before main() or an exported function ever runs.
Cricket analogy: Like a ground curator preparing a pitch to an exact specification before a single ball is bowled, Wasm's data section pre-loads memory with fixed bytes before any exported function ever executes.
(module
(memory (export "memory") 1)
(data (i32.const 0) "Hello, Wasm!")
(func $get_len (result i32)
i32.const 13)
(export "get_len" (func $get_len)))WAT and .wasm are semantically identical, but WAT is not commonly hand-written for real applications — it's primarily a debugging and learning tool. Production code is compiled from C, C++, Rust, or similar languages directly to the binary format.
- WAT is the human-readable text format that maps losslessly to and from the .wasm binary via wat2wasm/wasm2wat.
- Every WAT construct is written as a parenthesized S-expression starting with a keyword.
- Instructions can be written in flat 'linear' style or nested 'folded' style; both compile to the same result.
- Functions are declared with (func $name (param ...) (result ...) ...) and can be exported by string name.
- Locals and functions can be referenced either by symbolic $name or positional index.
- (memory N) allocates N pages of 64 KiB linear memory; (data (i32.const offset) "bytes") pre-initializes it.
- WAT is mainly used for debugging, teaching, and small hand-written examples, not production authoring.
Practice what you learned
1. What is WAT?
2. What syntax style does WAT use for all its constructs?
3. What does (export "add" (func $add)) do in a WAT module?
4. What does the (data (i32.const 0) "Hi") declaration do?
5. How can WAT instructions like i32.add be written?
Was this page helpful?
You May Also Like
The Wasm Execution Model
How WebAssembly actually executes: its stack machine, linear memory, module/instance/store relationship, and structured control flow.
What Is WebAssembly?
An introduction to WebAssembly (Wasm) as a portable, binary instruction format that lets languages like C, C++, and Rust run at near-native speed in browsers and beyond.
Compiling to WebAssembly
How real-world languages like C/C++, Rust, and others compile down to WebAssembly using toolchains such as Emscripten and wasm-pack.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentgRPC Study Notes
Protocol Buffers · 30 topics
Web DevelopmentSpring Boot Study Notes
Java · 30 topics
Web DevelopmentFlask Study Notes
Python · 30 topics
Web DevelopmentDjango Study Notes
Python · 30 topics
Web DevelopmentNext.js Study Notes
JavaScript · 30 topics