Base64 Encode & Decode in TypeScript

Encode or decode below — it runs locally in your browser — then grab the canonical TypeScript code. TypeScript adds no new Base64 APIs, but types let you build reusable, Unicode-safe wrappers around btoa/atob in the browser and Buffer in Node.js.

INPUT
OUTPUT
Type or paste to encode / decode

Encode and decode a string

In the browser, type Unicode-safe helpers around btoa/atob using TextEncoder and TextDecoder:

// base64.ts — browser-compatible, Unicode-safe

export function encodeBase64(input: string): string {
  const bytes = new TextEncoder().encode(input);
  let binary = '';
  bytes.forEach(byte => { binary += String.fromCharCode(byte); });
  return btoa(binary);
}

export function decodeBase64(input: string): string | null {
  try {
    const binary = atob(input);
    const bytes = Uint8Array.from(binary, c => c.charCodeAt(0));
    return new TextDecoder().decode(bytes);
  } catch {
    return null;
  }
}

Tip: btoa only handles Latin-1, so passing raw Unicode throws an InvalidCharacterError. Always go through TextEncoder first, and type the decoder as string | null so invalid Base64 is handled explicitly.

Base64 in Node vs browser

Node.js has no btoa/atob by default — use Buffer, which handles Unicode natively. In the browser you go through btoa/atob:

// Node.js
import { Buffer } from 'buffer';

export function encodeBase64(input: string | Buffer): string {
  const buf = typeof input === 'string' ? Buffer.from(input, 'utf8') : input;
  return buf.toString('base64');
}

export function decodeBase64(input: string): string {
  return Buffer.from(input, 'base64').toString('utf8');
}

// Browser equivalent: btoa(binary) / atob(input) via TextEncoder/TextDecoder

URL-safe Base64

For JWTs, URLs, and filenames, swap +// for -/_ and strip padding with a typed function:

export function encodeBase64URL(input: string): string {
  return encodeBase64(input)
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
}

export function decodeBase64URL(input: string): string | null {
  let base64 = input.replace(/-/g, '+').replace(/_/g, '/');
  while (base64.length % 4) base64 += '=';
  return decodeBase64(base64);
}

// Node 16+ shortcut:
// Buffer.from(str, 'utf8').toString('base64url')

Frequently asked questions

How do I Base64 encode a string in TypeScript?

Type a helper like encodeBase64(input: string): string. In the browser, build UTF-8 bytes with new TextEncoder().encode(input) and pass them to btoa; in Node.js, use Buffer.from(input, "utf8").toString("base64").

How do I Base64 decode in TypeScript?

In the browser, call atob(input), rebuild a Uint8Array, and decode with new TextDecoder().decode(bytes); return string | null for invalid input. In Node.js, use Buffer.from(input, "base64").toString("utf8").

What is the difference between btoa() and Buffer?

btoa/atob are browser-only and Latin-1, so Unicode needs TextEncoder/TextDecoder. Buffer is a Node.js class that handles all Unicode natively.

How do I do URL-safe Base64?

Replace + with -, / with _, and strip trailing =. In Node 16+, use Buffer.from(str).toString("base64url").

Need image, file, or URL-safe modes?

The main base64.dev tool handles text, images, files, and URL-safe Base64 with auto-detect.

Open base64.dev →