Skip to content

Getting Started

Terminal window
npm install zerobuf

You don’t need a WASM module to use zerobuf. Create a WebAssembly.Memory directly:

import { zerobuf } from "zerobuf";
const buf = zerobuf(new WebAssembly.Memory({ initial: 1 }));
const user = buf.create({
name: "alice",
scores: [95, 87, 92],
address: { city: "NYC", zip: "10001" },
});
// Read — defineProperty getters, reads from memory on access
console.log(user.name); // "alice"
console.log(user.scores[0]); // 95
// Write — directly to memory
user.name = "bob";
user.scores.push(88);
// Add new properties
user.email = "bob@example.com";

When sharing memory with WASM (Zig, Rust, C, etc.), pass the module’s memory and set startOffset past its static data:

import { zerobuf } from "zerobuf";
const wasm = await WebAssembly.instantiate(wasmBytes);
const memory = wasm.instance.exports.memory as WebAssembly.Memory;
// startOffset = past WASM's static data (e.g. __heap_base)
const buf = zerobuf(memory, wasm.instance.exports.__heap_base.value);
const point = buf.create({ x: 1.0, y: 2.0 });
wasm.instance.exports.transform(point.__zerobuf_ptr); // WASM reads/writes same memory
console.log(point.x); // reads WASM's output

Converts to a plain JS object. Use for hot loops or passing data over RPC (Proxy objects can’t be serialized).

const snap = user.toJS();
for (let i = 0; i < 10_000; i++) {
process(snap.name, snap.scores); // plain JS, no WASM access
}

When WASM writes a zerobuf object, wrap the pointer:

const resultPtr = wasm.instance.exports.computeResult() as number;
const result = buf.wrapObject(resultPtr);
console.log(result.score); // reads from WASM memory

Auto-grows with doubling strategy. Cap with maxPages:

const buf = zerobuf(memory, 0, { maxPages: 2048 }); // max 128MB

Max is 65535 pages (~4GB).