ArrayBuffer

Added in ves6 · Updated March 17, 2026 · Built-in Objects
javascript TypedArray binary es6

ArrayBuffer is a built-in object that represents a raw binary data buffer. It represents a fixed-length sequence of bytes that can be used to store and manipulate binary data in JavaScript. Unlike regular JavaScript arrays, ArrayBuffer stores raw binary data without any type interpretation.

Creating an ArrayBuffer

Create an ArrayBuffer using the new keyword with the ArrayBuffer constructor:

const buffer = new ArrayBuffer(16);
// ArrayBuffer { byteLength: 16 }

The constructor takes a single parameter:

  • length: The number of bytes to allocate (must be a non-negative integer)

If the requested byte length exceeds reasonable limits or is negative, a RangeError is thrown:

new ArrayBuffer(-1);   // RangeError: Invalid array length
new ArrayBuffer(Infinity); // RangeError: Invalid array length

ArrayBuffer Properties

byteLength

The byteLength property returns the size of the ArrayBuffer in bytes:

const buffer = new ArrayBuffer(64);
buffer.byteLength; // 64

This property is read-only and cannot be changed after the buffer is created.

ArrayBuffer Methods

slice()

Creates a shallow copy of a portion of the buffer into a new ArrayBuffer:

const buffer = new ArrayBuffer(8);

// Fill with some data
const view = new Uint8Array(buffer);
view[0] = 1;
view[1] = 2;
view[2] = 3;
view[3] = 4;

// Slice from byte 1 to 4 (exclusive)
const sliced = buffer.slice(1, 4);

sliced.byteLength; // 3
new Uint8Array(sliced); // Uint8Array [2, 3, 4]

Syntax: buffer.slice(start, end)

  • start: Start index (inclusive)
  • end: End index (exclusive)

ArrayBuffer.isView()

A static method that returns true if the argument is a view on an ArrayBuffer:

const buffer = new ArrayBuffer(8);

ArrayBuffer.isView(buffer);           // false
ArrayBuffer.isView(new Uint8Array(buffer));  // true
ArrayBuffer.isView(new DataView(buffer));    // true
ArrayBuffer.isView(new Int32Array(buffer, 0, 2)); // true

This is useful for type-checking before performing buffer operations.

ArrayBuffer.transfer() (ES2024)

Transfers ownership of an ArrayBuffer’s backing store to a new ArrayBuffer:

const original = new ArrayBuffer(16);
// Fill with some data
new Uint8Array(original).set([1, 2, 3, 4]);

const transferred = ArrayBuffer.transfer(original, 8);

original.byteLength;     // 0 (original is detached)
transferred.byteLength;  // 8
new Uint8Array(transferred); // Uint8Array [1, 2, 3, 4]

Syntax: ArrayBuffer.transfer(sourceBuffer, newLength)

  • sourceBuffer: The ArrayBuffer to transfer
  • newLength: The length of the new buffer in bytes

The original buffer becomes detached (byteLength becomes 0). If newLength is greater than the original length, the new bytes are zero-initialized.

ArrayBuffer.transferToFixedLength() (ES2024)

Similar to transfer() but always creates a fixed-length ArrayBuffer:

const resizable = new ArrayBuffer(16, { maxLength: 32 });
new Uint8Array(resizable).set([10, 20, 30]);

const fixed = ArrayBuffer.transferToFixedLength(resizable, 8);

resizable.byteLength;  // 0 (detached)
fixed.byteLength;     // 8
new Uint8Array(fixed); // Uint8Array [10, 20, 30, 0, 0, 0, 0, 0]

Key difference: transfer() may return a resizable buffer if the source was resizable, while transferToFixedLength() always returns a fixed-length buffer.

Working with ArrayBuffer

ArrayBuffer by itself doesn’t provide a way to read or write data. You need to use typed arrays or DataView to interact with the buffer’s contents.

Using TypedArrays

TypedArrays provide typed views into ArrayBuffer:

const buffer = new ArrayBuffer(16);

// Create different views on the same buffer
const uint8 = new Uint8Array(buffer);
const int32 = new Int32Array(buffer);
const float64 = new Float64Array(buffer);

// Write using one view
uint8[0] = 255;
uint8[1] = 255;
uint8[2] = 0;
uint8[3] = 0;

// Read using another view
int32[0];        // 65280 (0x0000FF in little-endian)
float64[0];      // 2.83...e-319

Different typed arrays interpret the same bytes differently:

  • Int8Array: 8-bit signed integer
  • Uint8Array: 8-bit unsigned integer
  • Int16Array: 16-bit signed integer
  • Uint16Array: 16-bit unsigned integer
  • Int32Array: 32-bit signed integer
  • Uint32Array: 32-bit unsigned integer
  • Float32Array: 32-bit floating point
  • Float64Array: 64-bit floating point

Using DataView

DataView provides low-level access to read/write different data types at specific offsets:

const buffer = new ArrayBuffer(12);
const dataView = new DataView(buffer);

// Write different types at specific offsets
dataView.setInt8(0, 42);
dataView.setUint16(2, 1000);
dataView.setFloat64(4, 3.14159);

// Read them back
dataView.getInt8(0);        // 42
dataView.getUint16(2);      // 1000
dataView.getFloat64(4);     // 3.14159

DataView is useful when you need to work with mixed data types in a single buffer.

Detached Buffers

An ArrayBuffer can become “detached” when ownership of its backing store is transferred. Once detached, the buffer’s byteLength becomes 0 and no views on it can be used:

const buffer = new ArrayBuffer(8);
const view = new Uint8Array(buffer);

view[0] = 1;

// Detach by transferring
const newBuffer = ArrayBuffer.transfer(buffer, 8);

view[0];       // 0 (view is now detached)
buffer.byteLength; // 0

Sharing Memory Between Workers

ArrayBuffer is the foundation for sharing memory between Web Workers:

// In main thread
const sharedBuffer = new SharedArrayBuffer(1024);
const sharedView = new Int32Array(sharedBuffer);

// Post the buffer to a worker
worker.postMessage({ sharedBuffer }, [sharedBuffer]);

// In worker
self.onmessage = (e) => {
  const sharedView = new Int32Array(e.data.sharedBuffer);
  // Both threads can now read/write directly
};

Practical Examples

Reading Binary File Data

// Simulating reading a binary header
function readHeader(buffer) {
  const view = new DataView(buffer);
  
  return {
    magic: view.getUint32(0),
    version: view.getUint16(4),
    flags: view.getUint16(6),
    dataSize: view.getUint32(8)
  };
}

const headerBuffer = new ArrayBuffer(12);
const headerView = new DataView(headerBuffer);
headerView.setUint32(0, 0x4A534F4E); // "JSON" in ASCII
headerView.setUint16(4, 1);          // version 1
headerView.setUint16(6, 0);          // flags
headerView.setUint32(8, 1024);       // data size

readHeader(headerBuffer);
// { magic: 1212766542, version: 1, flags: 0, dataSize: 1024 }

Buffer Reuse with Pooling

class BufferPool {
  constructor(size = 1024) {
    this.size = size;
    this.pool = [];
  }
  
  acquire() {
    if (this.pool.length > 0) {
      return this.pool.pop();
    }
    return new ArrayBuffer(this.size);
  }
  
  release(buffer) {
    if (buffer.byteLength === this.size) {
      this.pool.push(buffer);
    }
  }
}

const pool = new BufferPool(256);
const buf1 = pool.acquire();
// ... use buf1 ...
pool.release(buf1);

Browser Compatibility

MethodSupport
ArrayBufferES6 (all modern browsers)
slice()ES6
isView()ES6
transfer()ES2024 (limited)
transferToFixedLength()ES2024 (limited)

The ES2024 methods have limited browser support at the time of writing.

See Also