Node.js TypedArrays — Complete Guide to Binary Data with ArrayBuffer and TypedArray
In this tutorial, you will learn about Node.js TypedArrays. We cover key concepts, practical examples, and best practices to help you master this topic.
Node.js TypedArrays provide typed views over ArrayBuffer memory, enabling efficient manipulation of binary data with specific byte formats like int8, uint16, float64, and BigInt64.
What You'll Learn
By the end of this tutorial, you'll use TypedArrays and DataView for binary data, interoperate with Node.js Buffers, share memory between worker threads, and choose the right typed view.
Why TypedArrays Matter
TypedArrays offer deterministic memory layouts essential for binary protocols, audio processing, image manipulation, and WebAssembly interop. They are the backbone of modern Web APIs.
Real-World Use
A real-time audio processing application uses Float32Array to hold PCM audio samples, processes them with SIMD operations, and transfers the ArrayBuffer to a worker thread for encoding without copying.
TypedArrays Path
flowchart LR
A[Buffers] --> B[TypedArrays]
B --> C[File System]
C --> D[Worker Threads]
D --> E[Crypto]
B --> F{You Are Here}
style F fill:#f90,color:#fff
TypedArray Types
JavaScript provides nine TypedArray types: Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array.
const int8 = new Int8Array(4);
int8[0] = 127;
int8[1] = -128;
console.log("Int8Array:", int8);
const uint16 = new Uint16Array(4);
uint16[0] = 65535;
console.log("Uint16Array:", uint16);
const float64 = new Float64Array(4);
float64[0] = Math.PI;
console.log("Float64Array:", float64);
ArrayBuffer Fundamentals
ArrayBuffer is a fixed-length raw binary data buffer. TypedArrays and DataView provide views into it.
const buffer = new ArrayBuffer(16);
console.log("ArrayBuffer byte length:", buffer.byteLength);
const int32View = new Int32Array(buffer);
int32View[0] = 42;
int32View[1] = 100;
const uint8View = new Uint8Array(buffer);
console.log("Bytes:", Array.from(uint8View));
// Views share the same underlying ArrayBuffer memory
DataView for Heterogeneous Data
DataView provides methods to read and write different types at specific offsets, useful for binary protocols with mixed field types.
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setUint32(0, 0x12345678);
view.setUint16(4, 0xabcd);
view.setUint8(6, 0xff);
view.setUint8(7, 0x00);
console.log("Uint32 at 0:", view.getUint32(0).toString(16));
console.log("Uint16 at 4:", view.getUint16(4).toString(16));
console.log("Byte at 6:", view.getUint8(6).toString(16));
Buffer and TypedArray Interop
Node.js Buffer extends Uint8Array. Buffers can be created from ArrayBuffers and vice versa.
const buffer = Buffer.from("Hello Node.js");
console.log("Is Buffer a Uint8Array?", buffer instanceof Uint8Array);
const arrayBuffer = buffer.buffer.slice(
buffer.byteOffset,
buffer.byteOffset + buffer.byteLength
);
const typedArray = new Uint8Array(arrayBuffer);
console.log("TypedArray from Buffer:", typedArray);
const newBuffer = Buffer.from(typedArray.buffer);
console.log("Buffer from TypedArray:", newBuffer.toString());
Shared Memory with Worker Threads
Transfer ArrayBuffers between threads without copying using the transfer list.
const { Worker } = require("node:worker_threads");
const sharedBuffer = new SharedArrayBuffer(1024);
const sharedArray = new Int32Array(sharedBuffer);
sharedArray[0] = 42;
const worker = new Worker(`
const { parentPort } = require("worker_threads");
parentPort.on("message", (buf) => {
const arr = new Int32Array(buf);
arr[0] = arr[0] * 2;
parentPort.postMessage("done");
});
`, { eval: true });
worker.postMessage(sharedArray.buffer, [sharedArray.buffer]);
worker.on("message", () => console.log("Shared value:", sharedArray[0]));
Common Mistakes
1. Forgetting TypedArrays Are Views
Modifying a TypedArray modifies the underlying ArrayBuffer. Other views into the same buffer see the change.
2. Ignoring Endianness
DataView methods like getUint32 default to big-endian. Use the littleEndian parameter for cross-platform data.
3. Exceeding TypedArray Bounds
TypedArrays throw RangeError on out-of-bounds access. Always check length before writing.
4. Using Regular Arrays for Large Numeric Data
Regular arrays use double-precision and more memory. Use TypedArrays for performance-critical numeric data.
5. Forgetting ArrayBuffer Detachment
Transferring an ArrayBuffer to a worker thread detaches it. The original buffer becomes zero-length.
Practice Questions
1. What is the difference between TypedArray and DataView?
TypedArray provides uniform typed access (all elements same type). DataView allows mixed types at arbitrary offsets.
2. How do Node.js Buffers relate to TypedArrays?
Buffer extends Uint8Array. Every Buffer is also a Uint8Array with additional Node.js-specific methods.
3. What happens to an ArrayBuffer after transfer to a worker thread?
It is detached. The original ArrayBuffer becomes zero-length and cannot be used.
4. What is SharedArrayBuffer used for?
Shared memory accessible from multiple worker threads simultaneously. Use with Atomics for synchronization.
5. Challenge: Serialize a JavaScript object to binary using DataView.
function serialize(obj) {
const json = JSON.stringify(obj);
const buf = Buffer.from(json, "utf8");
const header = Buffer.alloc(4);
header.writeUInt32BE(buf.length, 0);
return Buffer.concat([header, buf]);
}
function deserialize(buffer) {
const length = buffer.readUInt32BE(0);
const json = buffer.subarray(4, 4 + length).toString("utf8");
return JSON.parse(json);
}
FAQ
Mini Project: Binary File Reader
Build a utility that reads binary file headers using DataView.
const fs = require("node:fs");
function readBinaryHeader(filePath) {
const fd = fs.openSync(filePath, "r");
const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);
const bytes = Buffer.alloc(16);
fs.readSync(fd, bytes, 0, 16, 0);
fs.closeSync(fd);
const uint8 = new Uint8Array(buffer);
uint8.set(bytes);
return {
magic: String.fromCharCode(view.getUint8(0), view.getUint8(1)),
version: view.getUint16(2, false),
size: view.getUint32(4, true),
flags: view.getUint32(8, true),
};
}
What's Next
Node.js File System Node.js Buffers Node.js Worker Threads
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro