Node.js · Events & Data

Buffers

Files, images, network packets and hashes are bytes, not text. A Buffer is Node’s container for raw bytes — and knowing how text becomes bytes avoids subtle bugs with emojis and non-English text.

Intermediate 5 min Lesson 12 of 37Examples target Node.js 22 LTS.
Before you start:Modules
0/37 in Node.js
On this page · 5 min · Intermediate

Learning objectives#

  • Create buffers from strings and arrays
  • Convert between utf8, hex and base64
  • Understand byte length vs character length
  • Slice, compare and concatenate buffers

Explanation#

A Buffer is a fixed-length sequence of bytes (0–255). Buffer.from("Hi") encodes text as UTF-8 bytes; Buffer.alloc(10) creates 10 zero bytes.

buf.toString("utf8" | "hex" | "base64") decodes or encodes the bytes. Base64 is common for embedding binary data in JSON or HTTP headers.

Characters are not bytes: "₹" is 1 character but 3 UTF-8 bytes; many emojis are 4 bytes. Use Buffer.byteLength(text) for sizes and HTTP Content-Length.

buf.subarray(start, end) creates a view (no copy) of part of a buffer; Buffer.concat([a, b]) joins buffers; buf.equals(other) compares contents.

fs.readFile without an encoding, crypto hashes and stream chunks all give you Buffers.

Syntax#

JavaScript Illustrative
const buf = Buffer.from('Hello', 'utf8');
buf.toString('hex');      // '48656c6c6f'
buf.toString('base64');   // 'SGVsbG8='
Buffer.byteLength('₹');   // 3

Code example: Text, bytes and encodings#

JavaScriptbuffers.js Illustrative
const text = 'Pay ₹500 ✅';


const buf = Buffer.from(text, 'utf8');
console.log('characters:', [...text].length, '| bytes:', buf.length);
console.log('first bytes:', buf.subarray(0, 4));
console.log('hex:', buf.toString('hex'));


const b64 = buf.toString('base64');
console.log('base64:', b64);
console.log('decoded:', Buffer.from(b64, 'base64').toString('utf8'));


// Basic auth header: base64("user:password")
const auth = 'Basic ' + Buffer.from('asha:s3cret').toString('base64');
console.log(auth);


// Joining and comparing
const joined = Buffer.concat([Buffer.from('Hello, '), Buffer.from('Node')]);
console.log(joined.toString(), joined.equals(Buffer.from('Hello, Node')));


// Raw bytes
const bytes = Buffer.from([72, 105, 33]);
console.log(bytes.toString(), bytes[0]);
Expected output
characters: 10 | bytes: 14
first bytes: <Buffer 50 61 79 20>
hex: 50617920e282b935303020e29c85
base64: UGF5IOKCuTUwMCDinIU=
decoded: Pay ₹500 ✅
Basic YXNoYTpzM2NyZXQ=
Hello, Node true
Hi! 72

This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.

Step-by-step explanation#

  1. The string has 10 characters, but ₹ and ✅ each take 3 bytes in UTF-8 (the other 8 characters take 1 byte each), so the buffer has 14 bytes.
  2. subarray(0, 4) shows the bytes for “Pay ” in hexadecimal.
  3. toString("base64") encodes; Buffer.from(b64, "base64") decodes back to the same text.
  4. HTTP Basic auth uses base64 of "user:password" — encoding, not encryption.
  5. Buffers can be joined, compared and built from raw byte values.

Real-world use case#

A payment webhook signs its body with HMAC; the API reads the raw request body as a Buffer, computes the signature over exactly those bytes, and compares it to the header — any re-encoding of the text would break the check.

Common mistakes#

Using string length for byte sizes

"₹500".length is 4, but it is 6 bytes. Use Buffer.byteLength for limits and headers.

Treating base64 as encryption

Anyone can decode base64. Use HTTPS and real encryption for secrets.

Decoding chunks one by one

A multi-byte character can be split across two stream chunks. Collect chunks and decode once, or use setEncoding / TextDecoder.

Best practices#

  • Be explicit about encodings
  • Measure with Buffer.byteLength
  • Use base64 only for transport
  • Concatenate chunks before decoding text

Remember this#

Buffer = bytes. String = characters.

₹ = 1 character, 3 bytes in UTF-8.

base64 is encoding, not encryption.

Practice exercise#

Your task: Write a function toBase64Url(text) that returns URL-safe base64 (replace + with -, / with _, and remove = padding). Test it with "Hello?>".

Need a hint?
Node also supports Buffer.from(text).toString("base64url").
Show solution
JavaScript Illustrative
function toBase64Url(text) {
  return Buffer.from(text).toString('base64')
    .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
console.log(toBase64Url('Hello?>'));                         // SGVsbG8_Pg
console.log(Buffer.from('Hello?>').toString('base64url'));   // SGVsbG8_Pg

Mini quiz#

Buffers quizPredict the output Question 1 of 3

What does Buffer.byteLength("₹") return?

Score so far: 0/0

Want more? Practise all Node.js MCQs · Node.js interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.