Skip to content

Linear Memory

WebAssembly functions work exclusively with numbers — i32, i64, f32, and f64. That is the complete set. There is no string type, no array type, no struct type. So how do you pass a string from JavaScript to a Wasm function, or build a dynamic array inside Wasm? The answer is linear memory.

Linear memory is a single, contiguous block of bytes that both WebAssembly and JavaScript can read and write. On the WebAssembly side you access it with instructions like i32.load and i32.store. On the JavaScript side you get a plain ArrayBuffer — the same object you already use with TypedArray views like Uint8Array and Int32Array.

The word “linear” means the address space is flat and one-dimensional: every byte has a numeric offset starting at 0, and addresses increase linearly up to the current size of the buffer. There are no pointers-to-pointers, no heap metadata visible to the language, just raw bytes at numeric offsets.

flowchart LR
  A["WebAssembly\n(i32.load / i32.store)"] --> B["Shared ArrayBuffer\n(linear memory)"]
  B --> A
  C["JavaScript\n(typed array views)"] --> B
  B --> C
Wasm and JS share one ArrayBuffer

Wasm’s numeric-only value model is a deliberate design choice that keeps the instruction set small, the execution engine simple, and performance predictable. But real programs need complex data — UTF-8 strings, byte arrays, structs with multiple fields. Linear memory provides the escape hatch:

  • Strings are stored as a sequence of UTF-8 bytes at some offset. You pass the offset (an i32) and the byte length (another i32) to a Wasm function instead of passing the string directly.
  • Arrays are a run of values written consecutively starting at a base address.
  • Structs are fields packed at fixed offsets from a base address, exactly like C structs.

JavaScript and Wasm both hold a reference to the same ArrayBuffer, so writes from one side are immediately visible on the other — no serialization, no copying.

The module below declares one page of memory and exports it so JavaScript can inspect it. The store42 function writes the number 42 as a 4-byte little-endian integer at byte offset 0. JavaScript then creates an Int32Array view over the buffer and reads that value back.

WebAssembly
What is WebAssembly linear memory?
Why do strings need to be stored in linear memory rather than passed directly to a Wasm function?
What JavaScript object backs WebAssembly linear memory?