Base64 in Node.js

Published

Node.js handles Base64 through Buffer, which is a subclass of Uint8Array. There is no need for btoa/atob (they exist, but only for browser compatibility).

Strings

const b64 = Buffer.from('Grüße 👋', 'utf8').toString('base64'); // "R3LDvMOfZSDwn5GL"
const text = Buffer.from(b64, 'base64').toString('utf8');        // "Grüße 👋"

Base64URL

Buffer.from('subject?').toString('base64url'); // "c3ViamVjdD8" (no padding)
Buffer.from('c3ViamVjdD8', 'base64url').toString();

The base64url encoding is built in since Node.js 15.7.

Files

import { readFile, writeFile } from 'node:fs/promises';

const b64 = (await readFile('photo.jpg')).toString('base64');
const dataUri = `data:image/jpeg;base64,${b64}`;

await writeFile('copy.jpg', Buffer.from(b64, 'base64'));

Streaming large files

Reading a 2 GB file into memory to encode it is a bad idea. Encode in chunks whose size is a multiple of 3 bytes so no padding appears in the middle:

import { createReadStream, createWriteStream } from 'node:fs';

const out = createWriteStream('big.b64');
let rest = Buffer.alloc(0);
for await (const chunk of createReadStream('big.bin', { highWaterMark: 3 * 64 * 1024 })) {
  const data = Buffer.concat([rest, chunk]);
  const usable = data.length - (data.length % 3);
  out.write(data.subarray(0, usable).toString('base64'));
  rest = data.subarray(usable);
}
out.end(rest.toString('base64'));

Validation: Buffer is lenient

Buffer.from(str, 'base64') silently skips invalid characters and stops at the first =. That is convenient for reading, but dangerous for validating API input. Check strictly with a regular expression and a round trip:

function isStrictBase64(s) {
  return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(s)
    && Buffer.from(s, 'base64').toString('base64') === s;
}

HTTP Basic authentication header

const auth = 'Basic ' + Buffer.from(`${user}:${password}`).toString('base64');
await fetch(url, { headers: { Authorization: auth } });

Try it in the HTTP request tool or decode an existing header with the Basic Auth decoder.

Comments (0)

Questions, ideas or a bug in “Base64 in Node.js”? Leave a comment, rate the tool, or reply to others.

No comments yet. Be the first to share your feedback!

Leave a comment

Rate this tool:
Esc
↑ ↓ move↵ openEsc close