JavaScript’s native Number type — an IEEE 754 double-precision float — is inefficient for binary data. Early solutions involved manual byte packing in plain arrays, which was slow and error-prone. ECMAScript 2015 formalized Typed Arrays, bringing C-like memory management to JavaScript. This three-layer architecture — ArrayBuffer, TypedArray views, and DataView — enables high-performance binary data processing in the browser and Node.js.
ArrayBuffer Foundation
ArrayBuffer represents a fixed-length raw binary buffer. It cannot be read or written directly — you must use a view:
const buffer = new ArrayBuffer(16); // 16 bytes
console.log(buffer.byteLength); // 16
Buffers can be transferred between Web Workers using structuredClone or resized with the resizable flag. The slice() method creates a partial copy. Importantly, the buffer itself has no type information — it is just a contiguous block of memory.
Typed Array Views
Typed array views provide a typed window into an ArrayBuffer. Each view interprets the buffer’s bytes as elements of a specific numeric type:
const buffer = new ArrayBuffer(8);
const int32 = new Int32Array(buffer); // 2 × 32-bit integers
const float64 = new Float64Array(buffer); // 1 × 64-bit float
Here is a complete reference of typed array types and their characteristics:
| Constructor | Element Size | C Equivalent | Common Use Case |
|---|---|---|---|
Int8Array | 1 byte | int8_t | Signed byte data |
Uint8Array | 1 byte | uint8_t | Raw byte streams |
Uint8ClampedArray | 1 byte | uint8_t | Canvas pixel data |
Int16Array | 2 bytes | int16_t | Audio samples |
Uint16Array | 2 bytes | uint16_t | Unicode code units |
Int32Array | 4 bytes | int32_t | Bitmap data |
Uint32Array | 4 bytes | uint32_t | Network packets |
Float32Array | 4 bytes | float | 3D graphics (WebGL) |
Float64Array | 8 bytes | double | Scientific computing |
BigInt64Array | 8 bytes | int64_t | Large integer IDs |
BigUint64Array | 8 bytes | uint64_t | Cryptography |
Creating a subarray without copying uses subarray():
const full = new Uint8Array([10, 20, 30, 40]);
const partial = full.subarray(1, 3); // [20, 30] — zero copy
DataView for Complex Structures
When a buffer contains mixed data types, DataView provides the flexibility you need. It allows reading and writing at arbitrary byte offsets with explicit type and endianness:
const buffer = new ArrayBuffer(8);
const dv = new DataView(buffer);
dv.setUint16(0, 0x4D42, true); // little-endian 'BM' signature
dv.setUint32(2, 1024, true); // file size
dv.setUint16(6, 54, true); // pixel offset
The littleEndian parameter is crucial for cross-platform compatibility. DataView is slightly slower than typed views due to its flexibility, but it is the correct tool for parsing binary file formats like BMP, PNG, or WAV headers.
Endianness and Cross-Platform Handling
Endianness refers to byte order: big-endian stores the most significant byte first, little-endian stores the least significant byte first. You can detect platform endianness at runtime:
const isLittleEndian = new Uint16Array(
new Uint8Array([0x12, 0x34]).buffer
)[0] === 0x3412;
Endianness matters when working with network protocols (TCP, WebSocket binary frames), file formats (PNG, WAV, MP4), and WebGPU buffer layouts. DataView’s explicit endian parameter eliminates all guesswork.
Canvas Pixel Manipulation
ImageData is backed by Uint8ClampedArray, enabling direct pixel access:
const ctx = canvas.getContext("2d");
const imageData = ctx.getImageData(0, 0, width, height);
const pixels = imageData.data; // Uint8ClampedArray
for (let i = 0; i < pixels.length; i += 4) {
const gray = 0.299 * pixels[i] + 0.587 * pixels[i+1] + 0.114 * pixels[i+2];
pixels[i] = pixels[i+1] = pixels[i+2] = gray; // grayscale
}
ctx.putImageData(imageData, 0, 0);
This approach is significantly faster than canvas filter methods and enables real-time video processing via requestAnimationFrame.
WebAssembly Memory Integration
Typed Arrays are the bridge between JavaScript and WebAssembly. WebAssembly.Memory is backed by an ArrayBuffer, allowing direct memory sharing:
const memory = new WebAssembly.Memory({ initial: 1 }); // 1 page = 64KB
const buffer = memory.buffer;
const view = new Uint8Array(buffer);
// Write data, call Wasm function, read results
This zero-copy model is the foundation of high-performance WebAssembly applications.
Performance Optimization
Typed arrays offer significant performance advantages over plain arrays for numeric data. Pre-allocate buffers with new ArrayBuffer(expectedSize) to avoid resizing. Use subarray() instead of slice() to avoid copying. Avoid hidden class transitions by keeping typed array access monomorphic. For arithmetic-heavy code, Float64Array leverages the CPU’s native double-precision pipeline.
Mastering binary data processing with Typed Arrays unlocks application domains including audio/video processing, WebAssembly, game development, and scientific computing. For mixed-type parsing, use DataView. For uniform numeric arrays, use typed views. For raw memory management, use ArrayBuffer directly.
