BufferWrap is a TypeScript library that simplifies working with structured binary data inside ArrayBuffers. Designed around the idea of a memory arena and pool allocator, It provides a proxy-based interface over raw buffers, making it ideal for GPU-style data pipelines, interleaved memory formats, particle systems, WebGPU/WebGL data, and more.
If you’re a developer building systems where performance and data layout matter, BufferWrap will save you time and eliminate bugs caused by manual memory handling. It offers the power of C-like struct access in JavaScript/TypeScript, with modern tools like generator-based iteration, lazy attribute extraction, and full support for shared memory.
BufferWrap is for developers building high-performance, real-time systems that work directly with memory:
It provides a BufferWrap<T> interface for struct access and mutation, using the Proxy layer that maps logical indices to memory regions.
npm install bufferwrap
import { BufferWrap } from "bufferwrap";
import { ArrayBufferStrategy } from "bufferwrap";
const wrap = new BufferWrap<{ id: number; pos: [number, number] }, ArrayBuffer>({
struct: {
id: { type: Uint8Array, length: 1 },
pos: { type: Float32Array, length: 2 },
},
capacity: 100,
strategy: ArrayBufferStrategy,
});
wrap.at(0).id = 123;
wrap.at(0).pos = [1.1, 2.2];
import { BufferWrap } from "bufferwrap";
import { NodeBufferStrategy } from "bufferwrap/node";
const wrap = new BufferWrap<{ id: number; pos: [number, number] }, Buffer>({
struct: {
id: { type: Uint8Array, length: 1 },
pos: { type: Float32Array, length: 2 },
},
capacity: 100,
strategy: NodeBufferStrategy,
});
wrap.at(0).id = 123;
wrap.at(0).pos = [1.1, 2.2];
Clone the repo and run:
npm install
npm test
To build and watch:
npm run build
npm run dev
Project Structure:
src/ – Core types, BufferWrap class, strategies, helperstests/ – Unit, integration, and strategy-specific testsindex.ts / index.node.ts / index.browser.ts – platform-specific entrypointsBufferWrap manages structured binary memory via 3 coordinated layers:
Owns the actual memory and read/write logic (ArrayBuffer, Node.js Buffer, etc.)
Manages the proxy cache, handles logical-to-physical mapping, updates proxies after inserts, moves, and slices.
Combines layout config, slicing logic, indexing API, and memory mutation helpers.
| Operation | Are Proxies Reused? | Are Proxies Invalidated? |
|---|---|---|
.at(index) |
✅ Yes | ❌ No |
.slice() |
✅ Yes (shared manager) | ❌ No |
.insert() |
✅ Remapped | ❌ No |
.move() |
✅ Remapped | ❌ No |
.copyInto() |
✅ Reused if compatible | ❌ No |
.from() |
❌ Cleared (fresh) | ✅ Yes |
BufferWrap<T> (e.g. wrap.at(5))BufferWrap lets you work only with logical indices. Strategies handle stride math and offset calculations internally.
| Error Message | Method |
|---|---|
insert(): Index X is out of bounds |
.insert() |
set(): Cannot set undefined for key |
.set() |
set(): Field "X" expects array of length N, got M |
.set() |
set(): Field "X" must be a JS array or TypeArray |
.set() |
insert(): incompatible BufferWrap struct or stride |
.insert() |
move(): Indices out of bounds |
.move() |
at(): Index X is out of bounds |
.at() |
get(): Unknown field key: "X" |
.get() |
MIT © 2025 Patrick Burris