Buffers & Binary Data
A Buffer is Node's fixed-length container for raw bytes, the building block it uses to handle files, network data, and any binary content that doesn't fit neatly into a text string.
Learn Buffers & Binary Data in our free Node.js course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Node.js course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
By the end of this lesson you'll be able to create buffers with from and alloc, convert between bytes and text in utf8, hex, and base64, read individual bytes, join buffers with concat, and understand why stream chunks arrive as Buffers.
What You'll Learn in This Lesson
1️⃣ Creating Buffers
There are two main ways to make a buffer. Buffer.from(string) takes text and encodes it as bytes (utf8 by default). Buffer.alloc(n) makes an empty, zero-filled buffer of n bytes that you can fill in yourself.
When you log a buffer, Node shows its bytes as hex (like ). You can index it like an array to read one byte, ask for its .length in bytes, and call .toString('utf8') to read it back as text.
2️⃣ Encodings: utf8, hex & base64
The same bytes can be displayed in different encodings. .toString('hex') shows each byte as two hex digits, handy for debugging. .toString('base64') packs the bytes into a compact, text-safe form often used for tokens, data URLs, and email attachments.
Going the other way, Buffer.from(str, 'base64') (or 'hex' ) decodes an encoded string back into the original bytes, which you can then read as 'utf8' text.
3️⃣ Joining Buffers & Streams
Because each buffer has a fixed size, you don't append to one — you combine several with Buffer.concat([a, b]) , which returns one new buffer containing all the bytes in order.
This is the exact pattern you use with streams : data arrives in pieces called chunks (each a Buffer), you push them into an array, and when the stream ends you Buffer.concat them into a single buffer to read as text or parse.
Your turn. Fill in the three blanks marked ___ , then run it and compare with the expected output.
No blanks this time — just a brief and an outline. Encoding a string to base64 and decoding it back is the foundation of countless real tasks (tokens, data URLs, basic auth headers). Write it yourself, run it, and check your output.
📋 Quick Reference — Buffers
Practice quiz
What is a Buffer in Node.js?
- A resizable string
- A network socket
- A fixed-length block of raw bytes
- A JSON object
Answer: A fixed-length block of raw bytes. A Buffer is a fixed-length chunk of raw bytes, used for files, network data, and binary content.
What does Buffer.from('Hello') create?
- A buffer of the utf8 bytes for 'Hello'
- The number 5
- A base64 string
- An empty buffer
Answer: A buffer of the utf8 bytes for 'Hello'. Buffer.from(string) encodes the text as bytes, utf8 by default, so 'Hello' becomes 5 bytes.
What is buf.length measured in?
- Characters
- Bits
- Words
- Bytes
Answer: Bytes. A buffer's length is the number of bytes, which may exceed the visible character count for multi-byte text.
What does Buffer.alloc(4) produce?
- A buffer with random leftover memory
- A zero-filled buffer of 4 bytes
- A 4-character string
- An error
Answer: A zero-filled buffer of 4 bytes. Buffer.alloc(n) creates an n-byte buffer that is zero-filled and safe to read immediately.
How does Buffer.alloc differ from Buffer.allocUnsafe?
- alloc zero-fills the memory; allocUnsafe may contain leftover data
- They are identical
- allocUnsafe is always zero-filled
- alloc is faster
Answer: alloc zero-fills the memory; allocUnsafe may contain leftover data. allocUnsafe skips zeroing for speed but may expose leftover memory; use alloc by default.
What does buf.toString('hex') return?
- The base64 form
- The original text
- Each byte as two hex digits
- The byte count
Answer: Each byte as two hex digits. .toString('hex') shows each byte as two hexadecimal digits, handy for debugging.
Is base64 a form of encryption?
- Yes, it hides secrets
- No, it is encoding that anyone can decode
- Yes, but only with a key
- No, it is compression
Answer: No, it is encoding that anyone can decode. base64 is encoding, not encryption. Anyone can decode it; it is for moving binary data through text channels.
How do you combine two buffers into one?
- a + b
- a.push(b)
- Buffer.join(a, b)
Buffers have a fixed size, so you combine several with Buffer.concat, which takes an array of buffers.
What does Buffer.concat([Buffer.from('Hello, '), Buffer.from('world!')]) have for .length?
- 12
- 13
- 2
- 6
Answer: 13. 'Hello, ' is 7 bytes and 'world!' is 6 bytes, so the joined buffer is 13 bytes.
By default, what type is each chunk delivered by a readable stream?
- A string
- A number
- A Buffer
- An array
Answer: A Buffer. Stream chunks are Buffers by default; you collect them and Buffer.concat at the end unless you set an encoding.