API reference

Binary data & typed arrays

9/9Coverage4/9Strict (zero caveats)

Raw byte buffers and the typed views over them, the layer every networking, crypto, and file-I/O path is built on. Every typed array is a general expression and knows its `.buffer` and `.byteOffset`. ArrayBuffer, DataView, SharedArrayBuffer, Atomics, and a real bigint-backed BigInt64Array/DataView 64-bit path are all here, so binary layouts round-trip byte-exactly, an embedded NUL included.

Exact Works, with caveats Not supported

ArrayBuffer

Exact
new ArrayBuffer(byteLength: number): ArrayBuffer

A fixed-length, zero-initialized (calloc'd) raw byte buffer, with .byteLength and .slice(start?, end?) (a copy, with array-slice negative-index/clamping rules). Unlike the TypedArrays below, it's a general expression — it works anywhere, not just in a variable declaration's initializer.

Parameters
byteLengthnumber
Size of the buffer in bytes.
Returns

ArrayBuffer — A zero-filled buffer.

const buf = new ArrayBuffer(8)
console.log(buf.byteLength)    // 8
const tail = buf.slice(-4)
console.log(tail.byteLength)   // 4
See it in a full example →

Uint8Array / Int8Array / Uint16Array / Int16Array / Uint32Array / Int32Array / Float32Array / Float64Array

Exact
new Uint8Array(size | ArrayBuffer | number[] | TypedArray)

Typed views over bytes, in three construction forms: a size (own new zero-filled buffer), an existing ArrayBuffer (a view sharing the same memory — writes through one view are visible through any other view over the same buffer, including a differently-typed one), the sub-range form new XArray(buf, byteOffset, length?), or a number[]/array literal/another TypedArray (a copy). Indexing, .length, the whole number[] HOF/iterator surface, plus the TypedArray-specific .set(source, offset?), .subarray(start?, end?) (a view, not a copy), .byteLength, and .buffer/.byteOffset (a view answers the buffer it was made over; an array with its own storage answers an ArrayBuffer made on first read and kept). Non-clamped writes wrap mod 2^width, matching real JS. Construction is a general expression — usable as a function argument, return value, object field, or method-chain head, not only a variable declaration's initializer.

Returns

TypedArray — A typed view or an own buffer.

const buf = new ArrayBuffer(8)
const bytes: Uint8Array = new Uint8Array(buf)
const ints: Int32Array = new Int32Array(buf)
bytes[0] = 1
console.log(ints[0])           // 1 — same 4 bytes as an i32
See it in a full example →

BigInt64Array / BigUint64Array

Works, with caveats
new BigInt64Array(size | bigint[] | TypedArray)

64-bit typed arrays whose elements are stored as raw i64/u64 but cross the language boundary as real arbitrary-precision bigint handles — writes require a bigint (a plain number is the spec's TypeError), reads wrap losslessly, so values above 2^53 round-trip exactly. Atomics load/store/RMW/compareExchange work on them, lowered to the same seq_cst i64 atomics.

Returns

BigInt64Array | BigUint64Array — A 64-bit typed array.

const bigs = new BigInt64Array(2)
bigs[0] = 9007199254740993n
console.log(bigs[0])            // 9007199254740993n
const ubigs = new BigUint64Array([18446744073709551615n])
console.log(ubigs[0])          // 18446744073709551615n
See it in a full example →
⚠ Differences from standard
  • Only an explicit method allow-list is supported — indexing r/w, .length/.byteLength, .at, .set, .subarray, .slice, .fill, .reverse, for-of, Atomics.*; everything else (.map/.filter/.reduce/.indexOf/.sort/.join/iterator objects/…) is a compile-time rejection, never a raw-scalar leak
  • Atomics.wait/notify stay Int32Array-only

Uint8ClampedArray

Exact
new Uint8ClampedArray(size | number[] | TypedArray)

A Uint8Array whose write path uses the spec's ToUint8Clamp instead of wrapping — values clamp to [0,255], floats round half to even (254.5 → 254, 255.5 → 255), and NaN → 0, on every write (element assignment including compound, construction, .set, .fill, and .map's result store). Reads are plain u8, so the entire read-side method surface works unchanged.

Returns

Uint8ClampedArray — A clamping byte array.

const clamped = new Uint8ClampedArray([-1, 300, 254.5, 255.5])
console.log(clamped[0], clamped[1], clamped[2], clamped[3]) // 0 255 254 255
See it in a full example →

DataView

supported
new DataView(buffer: ArrayBuffer, byteOffset?, byteLength?)

Endian-controlled binary access over an ArrayBuffer: full get/set × Int8..Uint32/Float16/Float32/Float64 and BigInt64/BigUint64 (real bigint values, unsigned above 2^63 correct) with the spec's per-call littleEndian flag (default big-endian), plus .byteLength/.byteOffset/.buffer (an aliasing-identical ArrayBuffer). V8's RangeErrors on out-of-bounds access and construction, and V8's inspect output. It is a Blob part and a TextDecoder input like any BufferSource.

Parameters
bufferArrayBuffer
The backing buffer.
byteOffsetnumber
Optional start offset.
byteLengthnumber
Optional view length.
Returns

DataView — A view for scalar reads/writes.

const buf = new ArrayBuffer(12);
const view = new DataView(buf);
view.setUint16(0, 0xCAFE);         // big-endian by default
view.setUint32(2, 123456789, true); // explicit little-endian
console.log(view.getUint32(2, true));
See it in a full example →

Blob

Exact
new Blob(parts?, { type, endings }?)

An immutable binary value with a MIME type, built from any iterable of strings, buffers, views and Blobs. The type is lowercased (or empty when not printable ASCII), and endings: 'native' converts line ends. Exposes .size/.type, .slice(start?, end?, contentType?) (a copy; type never inherited, per spec), .text()/.arrayBuffer()/.bytes() settling as Node's reader settles them, and .stream() → ReadableStream<Uint8Array>, one chunk per part.

Returns

Blob — An immutable binary blob.

const greeting = new Blob(["Hello, ", "world", "!"], { type: "text/plain" })
console.log(greeting.size, greeting.type) // 13 text/plain
console.log(await greeting.text())        // Hello, world!
See it in a full example →

SharedArrayBuffer

Works, with caveats
new SharedArrayBuffer(byteLength: number): SharedArrayBuffer

Identical representation to ArrayBuffer (all view constructions, .byteLength, .slice() — which returns a new SharedArrayBuffer, per spec — and DataView work unchanged), but postMessage/workerData/structuredClone share it by reference instead of deep-copying, the spec's semantics — and a view over it crosses as a view over the same memory. The backing memory for cross-thread Atomics.

Parameters
byteLengthnumber
Size in bytes.
Returns

SharedArrayBuffer — A reference-shared buffer.

const sab = new SharedArrayBuffer(8); // [0] counter, [1] done flag
const cells = new Int32Array(sab);
for (let i = 0; i < 1000; i++) {
  Atomics.add(cells, 0, 1);
}
See it in a full example →
⚠ Differences from standard
  • grow(n) requires the {maxByteLength} construction option (a compile-time rejection otherwise, where the spec throws a TypeError at run time); the maximum is reserved upfront

Atomics

Works, with caveats
Atomics.add/load/store/wait/notify/compareExchange(ta, i, ...)

load/store/add/sub/and/or/xor/exchange/compareExchange on any integer TypedArray including BigInt64Array/BigUint64Array (bigint operands/results), lowered directly to seq_cst LLVM atomics; float TypedArrays are a compile-time rejection. wait(ta, i, expected, timeoutMs?) returns "ok"/"not-equal"/"timed-out"; notify(ta, i, count?) returns the wake count — a portable futex substitute. Atomics.isLockFree(n) is true for 1/2/4/8.

Returns

number | bigint | string — The atomic result.

for (let i = 0; i < 1000; i++) {
  Atomics.add(cells, 0, 1);
}
const r: string = Atomics.wait(cells, 1, 0, 2000);
console.log("4-byte ops lock-free: " + Atomics.isLockFree(4));
See it in a full example →
⚠ Differences from standard
  • wait blocks the whole calling thread (event loop and fibers included) — allowed on the main thread (Node posture); no waitAsync
  • wait/notify are Int32Array-only (spec minus the BigInt64 half)
  • Index is bounds-unchecked, matching ordinary TypedArray indexing

Node Buffer (Buffer.from/.alloc/.toString(encoding)/.write/etc.)

Works, with caveats
Buffer.from(...) / Buffer.alloc(n) / buf.toString(enc)

A Buffer IS a Uint8Array — indexing, .length, .slice/.subarray, numeric .fill/.indexOf/.includes, HOFs, for-of, .set, .byteLength, and fs.writeFileSync(buffer) all share the TypedArray machinery; Buffer.from(...)/.alloc(...) are general expressions (call syntax, no vardecl restriction). Codecs both directions — utf8, utf16le/ucs2, hex, base64, base64url, latin1/binary/ascii — plus full read/write{U}Int{8,16,32}{LE,BE} + Float/Double + BigInt64/BigUInt64 accessors with catchable RangeError bounds checks.

Returns

Buffer — A Uint8Array-backed buffer.

const hello = Buffer.from("Hello");            // utf8 bytes
console.log(Buffer.from("4869", "hex").toString())      // Hi
console.log(hello.toString("base64"))          // SGVsbG8=
const pkt = Buffer.alloc(12)
pkt.writeBigInt64BE(9007199254740993n, 4)
See it in a full example →
⚠ Differences from standard
  • String-valued .indexOf/.includes/.lastIndexOf search the needle's UTF-8 bytes, and .fill(string, offset?, end?) repeats the needle's bytes (all no byteOffset/encoding); no 4-arg .write(string, offset, length, encoding) form; no .swap16/32/64, .toJSON, Buffer.of, Buffer.isAscii/Buffer.isUtf8, arbitrary-width readIntLE(offset, byteLength), poolSize