buffer
Buffer is a class unique to Node.js for handling fixed-length byte sequences (raw binary data) in memory. While JavaScript's String handles text, Buffer operates at the byte level, making it useful wherever binary data is needed — file I/O, network communication, encryption, and more.
Basic Syntax
// Create a Buffer from a string
var buf = Buffer.from('string', 'encoding');
// Allocate a Buffer of a fixed byte length (zero-initialized)
var buf2 = Buffer.alloc(byteLength);
// Convert to a string
var str = buf.toString('encoding');
Main Methods and Properties
| Method / Property | Description |
|---|---|
Buffer.from(data, encoding) | Creates a Buffer from a string, array, or ArrayBuffer. |
Buffer.alloc(size) | Creates a zero-initialized Buffer of the specified byte length. |
Buffer.allocUnsafe(size) | Creates an uninitialized Buffer. Faster, but may contain old data. |
Buffer.concat(list) | Concatenates multiple Buffers and returns a new Buffer. |
buf.toString(encoding) | Converts the Buffer to a string with the specified encoding. |
buf.length | Returns the byte length of the Buffer. |
buf.slice(start, end) | Returns a Buffer for the specified range (references the same memory). |
buf.subarray(start, end) | Performs the same operation as slice (recommended from Node.js v17). |
buf.copy(target) | Copies data into another Buffer. |
Buffer.compare(buf1, buf2) | Compares two Buffers in byte order. Returns 0 if equal, -1 or 1 based on ordering. |
buf.includes(value) | Checks whether the specified value is contained in the Buffer. |
buf.indexOf(value) | Returns the index of the first occurrence of the specified value, or -1 if not found. |
Buffer.from — Creating a Buffer from a String or Array
Buffer.from() creates a Buffer from a string or numeric array. When passing a string, specify the encoding as the second argument. If omitted, utf8 is used.
buffer_from.js
// Create a Buffer from a string (default is utf8)
var buf1 = Buffer.from('Yagami Iori\'s flame is blue');
console.log('Byte length:', buf1.length);
console.log('Contents:', buf1);
// Create a Buffer from a numeric array (each value is 0-255)
var buf2 = Buffer.from([75, 79, 70]); // ASCII: K, O, F
console.log('From array:', buf2.toString()); // KOF
// Convert a string to base64
var encoded = Buffer.from('Kusanagi Kyo').toString('base64');
console.log('base64 encoded:', encoded);
var decoded = Buffer.from(encoded, 'base64');
console.log('base64 decoded:', decoded.toString('utf8'));
node buffer_from.js Byte length: 26 Contents: <Buffer 59 61 67 61 6d 69 20 49 6f 72 69 27 73 20 66 6c 61 6d 65 20 69 73 20 62 6c 75 65> From array: KOF base64 encoded: S3VzYW5hZ2kgS3lv base64 decoded: Kusanagi Kyo
Buffer.alloc — Allocating a Fixed-Length Buffer
Buffer.alloc() creates a zero-initialized Buffer of the specified byte length. A fill value can be given as the second argument. Buffer.allocUnsafe() is a faster alternative that skips initialization, but old data may be present, so its use depends on the situation.
buffer_alloc.js
// Allocate 15 bytes, zero-initialized
var buf = Buffer.alloc(15);
console.log('Initial state:', buf); // all bytes are 0x00
// Initialize with a specific value (fill with 0xff)
var bufFilled = Buffer.alloc(5, 0xff);
console.log('Initialized with 0xff:', bufFilled);
// Write data byte by byte
buf[0] = 0x4b; // 'K'
buf[1] = 0x4f; // 'O'
buf[2] = 0x46; // 'F'
// Write Shiranui Mai's data into the Buffer
var name = Buffer.from('Shiranui Mai', 'utf8');
name.copy(buf, 3); // copy starting at byte 3 of buf
console.log('After writing:', buf.toString('utf8', 0, 3) + ' + ' + buf.toString('utf8', 3));
node buffer_alloc.js Initial state: <Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> Initialized with 0xff: <Buffer ff ff ff ff ff> After writing: KOF + Shiranui Mai
toString / Encoding Conversion
toString() converts a Buffer to a string. By specifying an encoding, you can convert to utf8, base64, hex, and other formats. The main encodings supported by Node.js are listed below.
| Encoding | Description |
|---|---|
utf8 | Default. Converts between strings and binary using UTF-8. |
base64 | Converts binary to printable ASCII characters. Used for email attachments, image Data URLs, etc. |
hex | Represents each byte as a 2-digit hexadecimal number. Used for debugging or verifying encrypted data. |
ascii | Handles ASCII characters only. Bytes outside the 7-bit range are discarded. |
binary / latin1 | Treats each byte as a latin1 character. |
encoding_convert.js
// Check Terry Bogard's ID data in each encoding
var data = Buffer.from('Terry Bogard - KOF Champion');
// utf8: read as a plain string
console.log('utf8 :', data.toString('utf8'));
// hex: display each byte as two hex digits
console.log('hex :', data.toString('hex'));
// base64: convert binary to ASCII string
var encoded = data.toString('base64');
console.log('base64:', encoded);
// Restore from base64
var restored = Buffer.from(encoded, 'base64').toString('utf8');
console.log('restored:', restored);
// Build data from hex for Ryo Sakazaki's record
var hexData = Buffer.from('526c726b6f', 'hex'); // hex representation of 'Rlrko'
console.log('from hex:', hexData.toString('ascii'));
node encoding_convert.js utf8 : Terry Bogard - KOF Champion hex : 546572727920426f67617264202d204b4f46204368616d70696f6e base64: VGVycnkgQm9nYXJkIC0gS09GIENoYW1waW9u restored: Terry Bogard - KOF Champion from hex: Rlrko
Buffer.concat / slice — Concatenation and Slicing
Buffer.concat() concatenates multiple Buffers, while slice() extracts a portion of a Buffer. Because slice() references the same memory region, modifying the result also changes the original Buffer. Use Buffer.from(buf.slice(...)) when an independent copy is needed.
concat_slice.js
// Concatenate multiple Buffers
var part1 = Buffer.from('Yagami Iori,');
var part2 = Buffer.from('Kusanagi Kyo,');
var part3 = Buffer.from('Terry Bogard');
var combined = Buffer.concat([part1, part2, part3]);
console.log('Concatenated:', combined.toString());
console.log('Total byte length:', combined.length);
// Buffer.compare compares two Buffers in byte order
var a = Buffer.from('Iori');
var b = Buffer.from('Kyo');
var result = Buffer.compare(a, b);
// 0: equal / -1: a < b / 1: a > b
console.log('compare result:', result); // -1 (I < K)
// slice extracts a portion (references the same memory as the original)
var slice = combined.slice(0, part1.length);
console.log('slice:', slice.toString());
node concat_slice.js Concatenated: Yagami Iori,Kusanagi Kyo,Terry Bogard Total byte length: 37 compare result: -1 slice: Yagami Iori,
Overview
Buffer is the foundation of binary data handling provided by Node.js. Use Buffer.from() to create a Buffer from existing data and Buffer.alloc() to reserve an empty byte region. toString() converts to utf8, base64, hex, and other formats, making Buffer the bridge between strings and binary.
Since Node.js v6, the new Buffer() constructor has been deprecated in favor of Buffer.from(), Buffer.alloc(), and Buffer.allocUnsafe(). For security reasons (risk of uninitialized memory leaks), alloc() is preferred over allocUnsafe() in many cases.
When receiving data from a stream, chunks arrive in Buffer format, so you encounter Buffer when handling data events from EventEmitter or reading with the fs module. The pattern of accumulating chunks with Buffer.concat() and then converting them all at once appears frequently in practice.
Common Mistakes
Common Mistake 1: Using new Buffer() (deprecated)
The new Buffer() constructor was deprecated in Node.js v6. When given a number as an argument, it had a security issue where memory was not initialized and old data could remain. Use Buffer.from(), Buffer.alloc(), and Buffer.allocUnsafe() according to your needs.
// Incorrect: new Buffer() is deprecated
var buf1 = new Buffer('Yagami Iori'); // DeprecationWarning
var buf2 = new Buffer(10); // uninitialized memory may contain old data
Correct approach:
// Correct: use factory functions suited to the purpose
var buf1 = Buffer.from('Yagami Iori'); // create from a string
var buf2 = Buffer.alloc(10); // 10-byte zero-initialized Buffer
var buf3 = Buffer.allocUnsafe(10); // uninitialized (faster, but may contain old data)
Common Mistake 2: buf.slice() references the same memory
buf.slice() references the same memory region as the original Buffer. Modifying the slice also changes the original Buffer. Use Buffer.from(buf.slice(...)) when you need an independent copy.
var original = Buffer.from('Kusanagi Kyo, Yagami Iori');
// Incorrect: slice references the same memory, so modifying it affects the original
var sliced = original.slice(0, 12); // 12 bytes for 'Kusanagi Kyo'
sliced[0] = 0x00; // modify the first byte of sliced
console.log(original.toString()); // the original Buffer changes too
When an independent copy is needed:
var original = Buffer.from('Kusanagi Kyo, Yagami Iori');
// Correct: Buffer.from() creates a copy (independent memory from the original)
var copied = Buffer.from(original.slice(0, 12));
copied[0] = 0x00; // modifying the copy
console.log(original.toString()); // the original Buffer is unchanged
Common Mistake 3: Confusing byte count with character count
buf.length returns the byte count. For multibyte characters such as Japanese, one character takes 3 bytes in UTF-8, so the character count and byte count do not match. To count characters, convert back to a string with toString() and then use .length.
var name = Buffer.from('Shiranui Mai'); // 12 characters (ASCII)
// Incorrect thinking: buf.length is bytes, not characters (for ASCII they happen to match,
// but with multibyte text they differ)
var jpName = Buffer.from('不知火舞'); // 4 characters in Japanese
console.log(jpName.length); // 12 (4 characters x 3 bytes each = 12 bytes)
To get character count:
var jpName = Buffer.from('不知火舞'); // 4 characters in Japanese
// Correct: convert to a string first, then use .length for character count
console.log(jpName.toString('utf8').length); // 4 (character count)
console.log(jpName.length); // 12 (byte count)
If you find any errors or copyright issues, please contact us.