~12 min read • Updated Dec 26, 2025
1. Creating Buffers
There are multiple ways to create Buffers:
const { Buffer } = require('node:buffer');
Buffer.alloc(10); // Zero-filled Buffer of length 10
Buffer.alloc(10, 1); // Buffer filled with value 1
Buffer.allocUnsafe(10); // Uninitialized Buffer (faster but unsafe)
Buffer.from([1, 2, 3]); // Buffer from array
Buffer.from('tést'); // Buffer from UTF-8 string
Buffer.from('tést', 'latin1'); // Buffer from Latin-1 string
2. Buffers and Encodings
When converting between Buffers and strings, an encoding can be specified. UTF-8 is the default.
Supported Encodings:
utf8: Default, multi-byte Unicodeutf16le: Unicode with little-endianlatin1: ISO-8859-1 single-byte encodingbase64andbase64url: Binary-to-text encodingshex: Each byte encoded as two hex charactersasciiandbinary: Legacy encodingsucs2: Alias of utf16le
const buf = Buffer.from('hello world', 'utf8');
console.log(buf.toString('hex')); // 68656c6c6f20776f726c64
console.log(buf.toString('base64')); // aGVsbG8gd29ybGQ=
3. Buffers and TypedArrays
Buffers are also Uint8Array instances, but there are subtle differences:
Buffer.slice()creates a view, not a copy.TypedArray.slice()creates a copy.
Example:
const buf = Buffer.from([1, 2, 3, 4]); const uint32array = new Uint32Array(buf); console.log(uint32array); // Uint32Array(4) [1, 2, 3, 4]
4. Shared Memory with TypedArray
Buffers can share memory with TypedArrays:
const buf = Buffer.from('hello', 'utf16le');
const uint16array = new Uint16Array(buf.buffer, buf.byteOffset, buf.length / 2);
console.log(uint16array); // Uint16Array(5) [104, 101, 108, 108, 111]
5. Iterating over Buffers
Buffers can be iterated using for..of:
const buf = Buffer.from([1, 2, 3]); for (const b of buf) console.log(b); // 1, 2, 3
6. The Blob Class
Blob encapsulates immutable raw data that can be shared across worker threads.
Features:
new Blob(sources[, options]): Create a Blob from strings, ArrayBuffers, TypedArrays, etc.blob.arrayBuffer(): Returns an ArrayBuffer copyblob.bytes(): Returns a Uint8Arrayblob.size: Size of the Blob in bytesblob.slice(): Create a new Blob from a subsetblob.stream(): Returns a ReadableStreamblob.text(): Returns contents as a UTF-8 stringblob.type: Content type
Example:
const { Blob } = require('node:buffer');
const blob = new Blob(['hello']);
blob.text().then(console.log); // "hello"
Conclusion
The Buffer class in Node.js is a powerful tool for handling binary data. With support for multiple encodings, compatibility with TypedArrays, and the addition of the Blob class, developers can efficiently process and transfer raw data. Buffers are essential for working with files, networking, and low-level data operations in Node.js.
1. Buffer.alloc(size[, fill[, encoding]])
Allocates a new Buffer of the specified size. If fill is provided, the Buffer is initialized with that value.
const buf = Buffer.alloc(5); //const buf2 = Buffer.alloc(5, 'a'); // const buf3 = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64'); //
2. Buffer.allocUnsafe(size)
Allocates a new Buffer without initializing memory. Faster, but may contain sensitive data. Use Buffer.alloc() for zero-filled Buffers.
const buf = Buffer.allocUnsafe(10); console.log(buf); // contents vary buf.fill(0); // overwrite with zeros
3. Buffer.allocUnsafeSlow(size)
Allocates a Buffer outside the internal pool. Useful when retaining small chunks of memory for long periods.
const sb = Buffer.allocUnsafeSlow(10); data.copy(sb, 0, 0, 10); store.push(sb);
4. Buffer.byteLength(string[, encoding])
Returns the number of bytes in a string or data structure, accounting for encoding.
const str = '½ + ¼ = ¾'; console.log(Buffer.byteLength(str, 'utf8')); // 12
5. Buffer.compare(buf1, buf2)
Compares two Buffers and returns -1, 0, or 1. Useful for sorting.
const buf1 = Buffer.from('1234');
const buf2 = Buffer.from('0123');
console.log([buf1, buf2].sort(Buffer.compare));
6. Buffer.concat(list[, totalLength])
Concatenates multiple Buffers into one.
const bufA = Buffer.concat([buf1, buf2, buf3], totalLength);
7. Buffer.copyBytesFrom(view[, offset[, length]])
Copies the memory of a TypedArray into a new Buffer.
const u16 = new Uint16Array([0, 0xffff]); const buf = Buffer.copyBytesFrom(u16, 1, 1);
8. Buffer.from(array)
Creates a Buffer from an array of bytes (0–255). Values outside the range are truncated.
const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); // "buffer"
9. Buffer.from(arrayBuffer[, byteOffset[, length]])
Creates a Buffer view over an ArrayBuffer or SharedArrayBuffer. Shares memory with the underlying ArrayBuffer.
const arr = new Uint16Array(2); arr[0] = 5000; arr[1] = 4000; const buf = Buffer.from(arr.buffer); console.log(buf); //
Conclusion
The Buffer class in Node.js is a powerful tool for binary data management. Its static methods provide safe and unsafe allocation, memory sharing, comparison, concatenation, and conversion from arrays and strings. Correct use of these methods ensures efficient and secure handling of raw data in Node.js applications.
1. Buffer.from(buffer)
Creates a new Buffer by copying data from an existing Buffer or Uint8Array.
const buf1 = Buffer.from('buffer');
const buf2 = Buffer.from(buf1);
buf1[0] = 0x61;
console.log(buf1.toString()); // auffer
console.log(buf2.toString()); // buffer
2. Buffer.from(object[, offsetOrEncoding[, length]])
For objects with valueOf() or Symbol.toPrimitive, creates a Buffer from the returned value.
const buf = Buffer.from(new String('this is a test'));
class Foo { [Symbol.toPrimitive]() { return 'this is a test'; } }
const buf2 = Buffer.from(new Foo(), 'utf8');
3. Buffer.from(string[, encoding])
Creates a Buffer from a string. Default encoding is UTF-8.
const buf1 = Buffer.from('this is a tést');
const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');
console.log(buf1.toString()); // this is a tést
console.log(buf2.toString()); // this is a tést
4. Buffer.isBuffer(obj)
Returns true if the object is a Buffer, false otherwise.
Buffer.isBuffer(Buffer.alloc(10)); // true
Buffer.isBuffer('string'); // false
5. Buffer.isEncoding(encoding)
Checks if the given encoding is supported.
Buffer.isEncoding('utf8'); // true
Buffer.isEncoding('utf/8'); // false
6. Buffer.poolSize
The size of the internal Buffer pool (default: 8192 bytes). This value can be modified.
7. buf[index]
Accesses or sets a byte at the given index. Valid values are 0–255.
const str = 'Node.js';
const buf = Buffer.allocUnsafe(str.length);
for (let i = 0; i < str.length; i++) buf[i] = str.charCodeAt(i);
console.log(buf.toString('utf8')); // Node.js
8. buf.buffer and buf.byteOffset
buffer references the underlying ArrayBuffer. byteOffset specifies the starting position within it.
const arrayBuffer = new ArrayBuffer(16); const buffer = Buffer.from(arrayBuffer); console.log(buffer.buffer === arrayBuffer); // true
9. buf.compare(target[, ...])
Compares two Buffers and returns -1, 0, or 1 based on sort order.
const buf1 = Buffer.from('ABC');
const buf2 = Buffer.from('BCD');
console.log(buf1.compare(buf2)); // -1
10. buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])
Copies data from one region of a Buffer to another or into a target Buffer.
const buf1 = Buffer.allocUnsafe(26);
const buf2 = Buffer.allocUnsafe(26).fill('!');
for (let i = 0; i < 26; i++) buf1[i] = i + 97;
buf1.copy(buf2, 8, 16, 20);
console.log(buf2.toString('ascii', 0, 25));
Conclusion
The Buffer class in Node.js provides powerful static methods and properties for binary data management. These include safe and unsafe allocation, validation, comparison, and copying. Mastering these methods ensures efficient and secure handling of raw data in Node.js applications.
1. buf.entries()
Returns an iterator of [index, byte] pairs from the Buffer.
const buf = Buffer.from('buffer');
for (const pair of buf.entries()) console.log(pair);
// [0, 98], [1, 117], ...
2. buf.equals(otherBuffer)
Checks if two Buffers contain exactly the same bytes.
const buf1 = Buffer.from('ABC');
const buf2 = Buffer.from('414243', 'hex');
console.log(buf1.equals(buf2)); // true
3. buf.fill(value[, offset[, end]][, encoding])
Fills the Buffer with a specified value.
const b = Buffer.allocUnsafe(10).fill('h');
console.log(b.toString()); // hhhhhhhhhh
4. buf.includes(value[, byteOffset][, encoding])
Checks if a Buffer contains a given value.
const buf = Buffer.from('this is a buffer');
console.log(buf.includes('this')); // true
console.log(buf.includes(97)); // true ('a')
5. buf.indexOf(value[, byteOffset][, encoding])
Returns the index of the first occurrence of a value, or -1 if not found.
const buf = Buffer.from('this is a buffer');
console.log(buf.indexOf('is')); // 2
6. buf.keys()
Returns an iterator of Buffer indexes.
const buf = Buffer.from('buffer');
for (const key of buf.keys()) console.log(key);
// 0, 1, 2, 3, 4, 5
7. buf.lastIndexOf(value[, byteOffset][, encoding])
Returns the index of the last occurrence of a value.
const buf = Buffer.from('this buffer is a buffer');
console.log(buf.lastIndexOf('buffer')); // 17
8. buf.length
Returns the number of bytes in the Buffer.
const buf = Buffer.alloc(1234); console.log(buf.length); // 1234
9. buf.readBigInt64BE / buf.readBigInt64LE
Reads a signed 64-bit integer from the Buffer in big-endian or little-endian format.
10. buf.readBigUInt64BE / buf.readBigUInt64LE
Reads an unsigned 64-bit integer from the Buffer in big-endian or little-endian format.
const buf = Buffer.from([0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff]); console.log(buf.readBigUInt64BE(0)); // 4294967295n
11. buf.readDoubleBE / buf.readDoubleLE
Reads a 64-bit double from the Buffer in big-endian or little-endian format.
const buf = Buffer.from([1,2,3,4,5,6,7,8]); console.log(buf.readDoubleBE(0));
Conclusion
These advanced Buffer methods provide fine-grained control over binary data. Iteration, equality checks, searching, and numeric reads make Buffers versatile for low-level programming tasks. Mastering these methods ensures efficient and reliable handling of raw data in Node.js applications.
1. Reading 32-bit Floats
buf.readFloatBE(offset): Reads a 32-bit float in big-endian format.buf.readFloatLE(offset): Reads a 32-bit float in little-endian format.
const buf = Buffer.from([1, 2, 3, 4]); console.log(buf.readFloatBE(0)); // 2.387939260590663e-38 console.log(buf.readFloatLE(0)); // 1.539989614439558e-36
2. Reading Int8 and UInt8
buf.readInt8(offset): Reads a signed 8-bit integer.buf.readUInt8(offset): Reads an unsigned 8-bit integer.
const buf = Buffer.from([-1, 5]); console.log(buf.readInt8(0)); // -1 console.log(buf.readUInt8(1)); // 254
3. Reading Int16 and UInt16
buf.readInt16BE(offset): Reads a signed 16-bit integer in big-endian format.buf.readInt16LE(offset): Reads a signed 16-bit integer in little-endian format.buf.readUInt16BE(offset): Reads an unsigned 16-bit integer in big-endian format.buf.readUInt16LE(offset): Reads an unsigned 16-bit integer in little-endian format.
const buf = Buffer.from([0x12, 0x34, 0x56]); console.log(buf.readInt16BE(0)); // 4660 console.log(buf.readUInt16LE(1)); // 5634
4. Reading Int32 and UInt32
buf.readInt32BE(offset): Reads a signed 32-bit integer in big-endian format.buf.readInt32LE(offset): Reads a signed 32-bit integer in little-endian format.buf.readUInt32BE(offset): Reads an unsigned 32-bit integer in big-endian format.buf.readUInt32LE(offset): Reads an unsigned 32-bit integer in little-endian format.
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]); console.log(buf.readUInt32BE(0).toString(16)); // 12345678 console.log(buf.readUInt32LE(0).toString(16)); // 78563412
5. Reading IntBE / IntLE
Reads a signed integer of variable length (1–6 bytes) in big-endian or little-endian format.
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); console.log(buf.readIntBE(0, 6).toString(16)); // 1234567890ab console.log(buf.readIntLE(0, 6).toString(16)); // -546f87a9cbee
6. Reading UIntBE / UIntLE
Reads an unsigned integer of variable length (1–6 bytes) in big-endian or little-endian format.
const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); console.log(buf.readUIntBE(0, 6).toString(16)); // 1234567890ab console.log(buf.readUIntLE(0, 6).toString(16)); // ab9078563412
Conclusion
The Buffer read methods provide precise control over extracting binary data in different formats. With support for signed and unsigned integers, and both big-endian and little-endian byte orders, these methods are essential for low-level data processing in Node.js applications.
1. buf.subarray(start, end)
Creates a new Buffer referencing the same memory as the original, cropped by start and end indexes. Changes in the subarray affect the original Buffer.
const buf1 = Buffer.allocUnsafe(26); for (let i = 0; i < 26; i++) buf1[i] = i + 97; const buf2 = buf1.subarray(0, 3); console.log(buf2.toString()); // abc buf1[0] = 33; console.log(buf2.toString()); // !bc
2. buf.slice(start, end)
Similar to subarray but deprecated. Changes in the slice also affect the original Buffer.
3. buf.swap16 / buf.swap32 / buf.swap64
Swaps byte order in-place:
swap16: for 16-bit integersswap32: for 32-bit integersswap64: for 64-bit integers
const buf = Buffer.from([1,2,3,4,5,6,7,8]); buf.swap16(); //
4. buf.toJSON()
Returns a JSON representation of the Buffer. Useful for serialization and reconstruction.
const buf = Buffer.from([1,2,3,4,5]);
console.log(JSON.stringify(buf));
// {"type":"Buffer","data":[1,2,3,4,5]}
5. buf.toString([encoding, start, end])
Decodes Buffer into a string. Default encoding is UTF-8.
const buf = Buffer.from('tést');
console.log(buf.toString('hex')); // 74c3a97374
console.log(buf.toString('utf8',0,3)); // té
6. buf.values()
Returns an iterator of Buffer values (bytes). Automatically used in for..of.
const buf = Buffer.from('buffer');
for (const val of buf) console.log(val);
// 98, 117, 102, ...
7. buf.write(string[, offset[, length]][, encoding])
Writes a string into the Buffer at the specified offset. If space is insufficient, only part of the string is written.
const buf = Buffer.alloc(256);
const len = buf.write('½ + ¼ = ¾', 0);
console.log(`${len} bytes: ${buf.toString('utf8',0,len)}`);
8. buf.writeBigInt64BE / buf.writeBigInt64LE
Writes a bigint as a signed 64-bit integer into the Buffer in big-endian or little-endian format.
const buf = Buffer.allocUnsafe(8); buf.writeBigInt64BE(0x0102030405060708n, 0); console.log(buf); //
Conclusion
Advanced Buffer methods such as subarray, swap, toJSON, toString, and write provide powerful tools for binary data management. They enable fast in-place transformations, serialization, decoding, and writing, making them vital for low-level programming in Node.js.
1. Writing BigUInt64
buf.writeBigUInt64BE(value, offset): Writes an unsigned 64-bit bigint in big-endian format.buf.writeBigUInt64LE(value, offset): Writes an unsigned 64-bit bigint in little-endian format.
const buf = Buffer.allocUnsafe(8); buf.writeBigUInt64BE(0xdecafafecacefaden, 0); console.log(buf); //
2. Writing Double and Float
buf.writeDoubleBE(value, offset): Writes a 64-bit floating-point number in big-endian format.buf.writeDoubleLE(value, offset): Writes a 64-bit floating-point number in little-endian format.buf.writeFloatBE(value, offset): Writes a 32-bit floating-point number in big-endian format.buf.writeFloatLE(value, offset): Writes a 32-bit floating-point number in little-endian format.
const buf = Buffer.allocUnsafe(8); buf.writeDoubleBE(123.456, 0); console.log(buf);
3. Writing Small Integers
buf.writeInt8(value, offset): Writes a signed 8-bit integer.buf.writeUInt8(value, offset): Writes an unsigned 8-bit integer.
const buf = Buffer.allocUnsafe(2); buf.writeInt8(2, 0); buf.writeInt8(-2, 1); console.log(buf); //
4. Writing Int16 and UInt16
buf.writeInt16BE(value, offset): Writes a signed 16-bit integer in big-endian format.buf.writeInt16LE(value, offset): Writes a signed 16-bit integer in little-endian format.buf.writeUInt16BE(value, offset): Writes an unsigned 16-bit integer in big-endian format.buf.writeUInt16LE(value, offset): Writes an unsigned 16-bit integer in little-endian format.
5. Writing Int32 and UInt32
buf.writeInt32BE(value, offset): Writes a signed 32-bit integer in big-endian format.buf.writeInt32LE(value, offset): Writes a signed 32-bit integer in little-endian format.buf.writeUInt32BE(value, offset): Writes an unsigned 32-bit integer in big-endian format.buf.writeUInt32LE(value, offset): Writes an unsigned 32-bit integer in little-endian format.
6. Writing IntBE / IntLE and UIntBE / UIntLE
Writes integers of variable length (1–6 bytes) in big-endian or little-endian format.
const buf = Buffer.allocUnsafe(6); buf.writeIntBE(0x1234567890ab, 0, 6); console.log(buf); //
7. Writing Strings
buf.write(string[, offset[, length]][, encoding]): Writes a string into the Buffer using the specified encoding (default: UTF-8).
const buf = Buffer.alloc(256);
const len = buf.write('½ + ¼ = ¾', 0);
console.log(`${len} bytes: ${buf.toString('utf8',0,len)}`);
Conclusion
The Buffer write methods provide precise control over storing binary data in different formats. With support for signed and unsigned integers, floating-point numbers, big integers, and strings, these methods are essential for low-level data processing in Node.js applications.
Written & researched by Dr. Shahin Siami