Question

How to Encode and Decode Base64 Strings in JavaScript

csharpbase64

Question

How can I convert a normal string into a Base64-encoded string?

How can I also decode a Base64-encoded string back into a regular string?

I want to understand both directions clearly:

  • encoding a string to Base64
  • decoding a Base64 string back to text

Short Answer

By the end of this page, you will understand what Base64 is, when to use it, and how to encode and decode strings in JavaScript. You will also learn the difference between browser and Node.js approaches, how Unicode affects Base64 conversion, and how to avoid common mistakes.

Concept

Base64 is a way to represent binary or text data using only a limited set of readable ASCII characters.

It is commonly used when data needs to be safely transported through systems that expect text instead of raw bytes.

Why Base64 exists

Some systems do not handle raw binary data well. For example:

  • JSON and text-based APIs often expect text
  • Email formats may restrict allowed characters
  • Data URLs embed file content as text
  • Tokens or small payloads may be transmitted as text

Base64 solves this by converting data into a string made from characters like:

  • A-Z
  • a-z
  • 0-9
  • +
  • /
  • and sometimes = for padding

Important idea

Base64 is encoding, not encryption.

That means:

  • it changes the format of data
  • it does not protect the data
  • anyone can decode it easily

If you need security, use encryption or hashing for the right purpose.

Why this matters in real programming

Developers use Base64 when they need to:

  • include file content in text responses
  • send binary data through APIs
  • store simple encoded values in configuration or transport layers
  • work with authentication headers such as Basic Auth

In JavaScript, the exact method depends on where your code runs:

  • Browser: often btoa() and atob()
  • Node.js: commonly Buffer

For modern JavaScript, Buffer is the most reliable option in Node.js, especially for Unicode text.

Mental Model

Think of Base64 like repacking an object into a standard shipping box.

  • Your original string is the item
  • Base64 is the box format
  • Encoding puts the item into the box
  • Decoding takes the item back out

The box makes transport easier, but it does not lock or protect the item.

So if someone receives the box, they can still open it and see what is inside.

Take Quiz

Syntax and Examples

Browser examples

In browsers, you can use btoa() to encode and atob() to decode ASCII text.

const text = "hello world";
const encoded = btoa(text);
const decoded = atob(encoded);

console.log(encoded); // aGVsbG8gd29ybGQ=
console.log(decoded); // hello world

Explanation

  • btoa(text) converts a string to Base64
  • atob(encoded) converts Base64 back to a string

Node.js examples

In Node.js, use Buffer.

const text = "hello world";
const encoded = Buffer.from(text, "utf8").toString("base64");
const decoded = Buffer.from(encoded, "base64").toString("utf8");

console.log(encoded); // aGVsbG8gd29ybGQ=
console.log(decoded); // hello world

Explanation

  • Buffer.from(text, "utf8") turns text into bytes
  • .toString("base64") converts those bytes to Base64
  • Buffer.from(encoded, "base64") reads Base64 data
  • .toString("utf8") converts the bytes back to normal text

Unicode-safe example in Node.js

const text = "こんにちは";
const encoded = Buffer.from(text, "utf8").toString("base64");
const decoded = Buffer.from(encoded, "base64").toString("utf8");

console.log(encoded);
console.log(decoded); // こんにちは

This works correctly because Buffer handles UTF-8 text properly.

Reusable helper functions

function encodeBase64(text) {
  return Buffer.from(text, "utf8").toString("base64");
}

function decodeBase64(base64Text) {
  return Buffer.from(base64Text, "base64").toString("utf8");
}

console.log(encodeBase64("JavaScript"));
console.log(decodeBase64("SmF2YVNjcmlwdA=="));

Step by Step Execution

Consider this Node.js example:

const text = "cat";
const encoded = Buffer.from(text, "utf8").toString("base64");
const decoded = Buffer.from(encoded, "base64").toString("utf8");

console.log(encoded);
console.log(decoded);

Step 1: Start with the original string

const text = "cat";

The variable text stores the regular string cat.

Step 2: Convert the string into bytes

Buffer.from(text, "utf8")

Node.js creates a buffer from the string using UTF-8 encoding.

Step 3: Convert those bytes to Base64

.toString("base64")

The bytes are represented as a Base64 string.

For cat, the result is:

Y2F0

So now:

const encoded = "Y2F0";

Step 4: Decode the Base64 string back into bytes

Buffer.from(encoded, "base64")

Node.js reads Y2F0 as Base64 data and converts it back to bytes.

Step 5: Convert bytes back into a normal string

.toString("utf8")

Those bytes are turned back into the original text:

cat

Final output

Y2F0
cat

Real World Use Cases

Common uses of Base64

Sending binary data in JSON

APIs sometimes include image data or file content as Base64 because JSON is text-based.

const fileContent = "example text";
const base64 = Buffer.from(fileContent, "utf8").toString("base64");

const payload = {
  filename: "note.txt",
  content: base64
};

Basic Authentication headers

A username and password can be joined and Base64-encoded for an HTTP Authorization header.

const credentials = "user:password";
const encoded = Buffer.from(credentials, "utf8").toString("base64");

console.log(`Basic ${encoded}`);

Data URLs in the browser

Small files can be embedded directly into HTML or CSS as Base64 data URLs.

Logging or transport-safe conversion

Sometimes data is encoded so it can be passed through systems that only accept plain text.

When not to use it

Base64 increases size by roughly one-third, so it is not always ideal for large files.

For large binary uploads, sending raw file data is often better.

Take Quiz

Real Codebase Usage

In real projects, developers usually wrap Base64 logic in helper functions instead of repeating conversion code everywhere.

Common patterns

Utility helpers

function toBase64(value) {
  return Buffer.from(value, "utf8").toString("base64");
}

function fromBase64(value) {
  return Buffer.from(value, "base64").toString("utf8");
}

This keeps encoding logic consistent.

Validation before decoding

Applications often validate input before trying to decode it.

function safeDecodeBase64(value) {
  try {
    return Buffer.from(value, "base64").toString("utf8");
  } catch {
    return null;
  }
}

Guard clauses

function decodeIfPresent(value) {
  if (!value) {
    return "";
  }

  return Buffer.from(value, "base64").toString("utf8");
}

Configuration and secrets transport

Some deployment systems store values in Base64 form. In code, developers decode them at startup.

const encodedConfig = process.env.APP_CONFIG_BASE64;
const configText = encodedConfig
  ? Buffer.from(encodedConfig, "base64").toString("utf8")
  : "{}";

Practical advice

  • Use Buffer in Node.js
  • Be careful with Unicode in browser code
  • Validate external input before decoding
  • Do not treat Base64 as security

Common Mistakes

1. Thinking Base64 is encryption

Broken assumption:

const secret = Buffer.from("myPassword", "utf8").toString("base64");

This is not secure storage. Anyone can decode it.

Avoid it by

  • using hashing for passwords
  • using encryption for confidential data

2. Using btoa() with Unicode text

Broken browser example:

const text = "こんにちは";
const encoded = btoa(text); // may fail or produce incorrect results

btoa() is designed for ASCII-like input, not general Unicode text.

Avoid it by

Using proper UTF-8 handling or using Buffer in Node.js.

3. Forgetting the input encoding in Node.js

Less clear version:

Buffer.from(text).toString("base64");

This often works, but being explicit is better for learning and maintenance.

Better

Buffer.from(text, "utf8").toString("base64");

4. Decoding invalid input without checks

Potentially unsafe:

const decoded = Buffer.from(userInput, "base64").toString("utf8");

If userInput comes from outside your app, validate it first.

5. Mixing up bytes and text

Base64 represents bytes, not just strings. If you are dealing with files, images, or buffers, think in terms of binary data first.

Comparisons

ApproachEnvironmentGood forLimitation
btoa() / atob()BrowserSimple ASCII textNot reliable for general Unicode text
BufferNode.jsText and binary dataNode-specific API
Custom UTF-8 wrapper around btoa()BrowserUnicode support when neededMore code and easier to get wrong

Base64 vs encryption

ConceptPurposeCan it be easily reversed?
Base64Data encodingYes
EncryptionProtect dataOnly with the correct key
HashingOne-way verificationNo practical reversal

Base64 vs URL encoding

ConceptMain use
Base64Represent binary or text data as ASCII
URL encodingMake characters safe inside URLs

They solve different problems and are not interchangeable.

Take Quiz

Cheat Sheet

Node.js

Encode:

Buffer.from(text, "utf8").toString("base64")

Decode:

Buffer.from(base64Text, "base64").toString("utf8")

Browser

Encode ASCII text:

btoa(text)

Decode ASCII text:

atob(base64Text)

Rules to remember

  • Base64 is encoding, not security
  • Use Buffer in Node.js for reliable UTF-8 handling
  • btoa() and atob() are fine for simple ASCII text in browsers
  • Base64 output often ends with = padding
  • Base64 makes data larger, not smaller

Common examples

Buffer.from("hello", "utf8").toString("base64")
// aGVsbG8=

Buffer.from("aGVsbG8=", "base64").toString("utf8")
// hello

Edge cases

  • Unicode text needs proper UTF-8 handling
  • Invalid external input should be validated before decoding
  • Large files are usually better handled as binary streams, not Base64 strings

FAQ

What is Base64 used for in JavaScript?

Base64 is used to convert text or binary data into a text-safe format for transport in APIs, JSON, headers, and data URLs.

How do I encode a string to Base64 in Node.js?

Use:

Buffer.from(text, "utf8").toString("base64")

How do I decode a Base64 string in Node.js?

Use:

Buffer.from(base64Text, "base64").toString("utf8")

Can I use btoa() and atob() in all JavaScript environments?

No. They are primarily browser APIs. In Node.js, Buffer is the standard approach.

Why does Base64 decoding fail for some characters?

This usually happens because of Unicode handling issues or because the input is not valid Base64.

Is Base64 secure for passwords or secrets?

No. Base64 is not security. It is easy to decode.

Why does a Base64 string end with =?

The = character is padding used to make the encoded output fit Base64's required length format.

Does Base64 reduce file size?

No. It increases the size of the data.

Take Quiz

Mini Project

Description

Build a small JavaScript utility that can both encode plain text into Base64 and decode Base64 back into plain text. This demonstrates the two-way conversion developers often use in scripts, backend services, and debugging tools.

Goal

Create reusable functions that encode and decode strings using Base64 and test them with sample input.

Requirements

  • Create one function to encode a normal string into Base64.
  • Create one function to decode a Base64 string back into normal text.
  • Use UTF-8 so regular text is handled correctly.
  • Print the original text, encoded text, and decoded text.
  • Test the program with at least one sample string.
Take Quiz

Keep learning

Related questions

View more