Featured image of post JavaScript Typed Arrays: Binary Data Processing in the Browser Featured image of post JavaScript Typed Arrays: Binary Data Processing in the Browser

JavaScript Typed Arrays: Binary Data Processing in the Browser

Master JavaScript Typed Arrays for binary data processing: ArrayBuffer, TypedArray views, DataView, endianness, WebAssembly integration, and Canvas pixel manipulation.

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:

ConstructorElement SizeC EquivalentCommon Use Case
Int8Array1 byteint8_tSigned byte data
Uint8Array1 byteuint8_tRaw byte streams
Uint8ClampedArray1 byteuint8_tCanvas pixel data
Int16Array2 bytesint16_tAudio samples
Uint16Array2 bytesuint16_tUnicode code units
Int32Array4 bytesint32_tBitmap data
Uint32Array4 bytesuint32_tNetwork packets
Float32Array4 bytesfloat3D graphics (WebGL)
Float64Array8 bytesdoubleScientific computing
BigInt64Array8 bytesint64_tLarge integer IDs
BigUint64Array8 bytesuint64_tCryptography

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.