Some network protocols, such as HTTP, SMTP, and JSON, can only handle text-based data.
JavaScript has several built-in functions that convert raw binary data into a textual representation before sending it over a network. These functions rely on Base64 encoding.
Learn how Base64 encoding and decoding work in JavaScript and apply them to files, API payloads, and other binary data.

What Is Base64?
Base64 is an encoding system that converts binary data into text. It does not encrypt or compress data; it just represents it using human-readable characters. The system uses 64 symbols, including letters, digits, and special characters from the ASCII character set.

Developers use Base64 to store or transmit binary data, like images, files, or cryptographic keys, through systems that handle only text, such as email, JSON, or XML.
Without Base64 encoding, those systems can misinterpret raw binary bytes as control codes, which can lead to transmission errors and corrupt the data.
Base64 Use Cases
The Base64 encoding system is widely used in many real-world scenarios:
- Sending images or files over text-based protocols. Protocols like HTTP and SMTP only understand text. Without Base64 encoding, there is no guarantee that images, documents, or other binary data will pass through these channels intact.
- Embedding small resources directly into web pages. Instead of linking to external resources, developers can embed icons, fonts, or background images directly in HTML, CSS, or SVG. It is a convenient way to reduce the number of HTTP requests and speed up page loading times for small assets.
- Attaching files in emails. Email protocols like SMTP are designed for plain text transfers, not binary files. To overcome this limitation, the MIME standard uses Base64 to encode attachments as text before sending them.
- Encoding credentials or tokens in HTTP headers. Many APIs use the Authorization: Basic header in their authentication flows. It relies on Base64 encoding to convert credentials or bearer tokens into text so they can be sent in HTTP headers.
- Including binary data in API requests and responses. Some APIs need to send or receive binary files, like images or generated reports, in JSON, XML, or other text-based formats. Base64 encoding solves this problem by converting binary data into text so it can be included in API payloads.
Base64 Limitations
Limitations of the Base64 encoding system include:
- Bloated file sizes. Base64-encoded data is larger than the original binary version. This might not matter for small icons or tokens, but it becomes inefficient when transferring or storing larger files, such as PDFs, images, or videos.
- No security benefit. Base64 is easy to decode, and it does not hide or protect your data. For actual protection, use strong RSA or AES encryption protocols and always send sensitive information over HTTPS.
- Performance overhead. Encoding and decoding run on the same thread that manages the DOM. Large conversions can increase processing time, making web pages feel slow or unresponsive. This is especially true in client-side JavaScript or on resource-limited devices like phones and tablets.
- Unicode handling issues. JavaScript strings are UTF-16 encoded; however, Base64 operates on bytes, not characters. This means you need to convert text to bytes (UTF-8) before encoding, and back again after decoding. Without this conversion, the data can become corrupted or cause unexpected application errors.
- Difficult to debug or read. Base64 strings are long and difficult to read. This makes log and config files harder to understand and troubleshoot. Try to keep binary data separate from your code or text files, rather than embedding it directly into HTML or configuration files.
Methods for Encoding and Decoding Strings with Base64
JavaScript has several methods for encoding and decoding data in Base64. The best method to use depends on whether you are working in the browser, Node.js, or both.
| Browser Methods | Use Case |
|---|---|
btoa() | Encodes ASCII text to Base64. |
atob() | Decodes Base64-encoded ASCII text back to binary. |
| Node.js Methods | Use Case |
|---|---|
Buffer.from() | Encodes data in Node.js. Supports UTF-8, binary, and other encodings. |
Buffer.from() | Decodes encoded data back to a string. |
| Browser+Node.js | Use Case |
|---|---|
TextEncoder | Converts strings to UTF-8 byte arrays before encoding them to Base64. |
TextDecoder | Converts strings to UTF-8 byte arrays and then back into strings. Use when working with non-ASCII or Unicode data. |
Encoding with btoa() Method
The btoa() function in JavaScript encodes ASCII text, or binary data represented as text, into a Base64 string. It is built into modern browsers, and you can run it in the Developer Console.
Access your browser's console (Ctrl+Shift+J in Chrome, Ctrl+Shift+K in Firefox) and run the following JavaScript code:
const text = "Pretty Picture";
const encoded = btoa(text);
console.log(encoded);
btoa() takes groups of 3 bytes (24 bits total) from the Pretty Picture string and splits them into 4 groups of 6 bits. Each group is mapped to one of the 64 characters in the Base64 alphabet. The output is a Base64-encoded string:
UHJldHR5IFBpY3R1cmU=

You can now embed the encoded string in HTML or CSS, send it over HTTP, or store it in a text file.
This method only works with ASCII-safe characters. For input that includes characters outside the ASCII set, use the TextEncoder interface instead.
Decoding with atob() Method
The atob() function decodes a Base64-encoded string back into its original text or binary form. It reverses the process performed by the btoa() function.
To decode the string from the previous example, enter the following JavaScript code in your browser's console:
const encoded = "UHJldHR5IFBpY3R1cmU=";
const decoded = atob(encoded);
console.log(decoded);
The output represents the decoded version of the UHJldHR5IFBpY3R1cmU= string:
Pretty Picture

The decoded string can now be displayed on a webpage, parsed as text, or processed in scripts.
The atob() function works only with ASCII characters. For decoding non-ASCII data, you need to use the TextDecoder interface, which is available in all modern browsers.
Using the Buffer Class in Node.js
Node.js does not include btoa() or atob() functions. The standard way to process data in server-side Node.js applications is through the built-in Buffer class.
The Buffer class supports a wide range of data formats, from Unicode text to raw bytes. You can use the Buffer.from() method to encode a string into Base64:
const text = "Cyberpunk: Edgerunners が好きです。";
const encoded = Buffer.from(text, "utf8").toString("base64");
console.log(encoded);
In this example, the Buffer.from() method converts the UTF-8 text into binary data, and .toString("base64") encodes that data into Base64 text:
Q3liZXJwdW5rOiBFZGdlcnJ1bm5lcnMg44Go5L2P44GX44Gf44CCI
Use the reverse process to decode the string:
const decoded = Buffer.from(encoded, "base64").toString("utf8");
console.log(decoded);
Here, Buffer.from() interprets the input as Base64, decodes it into binary data, and then converts it back to UTF-8 text:
Cyberpunk: Edgerunners が好きです。
Note: If you are building dynamic web applications, the MEAN stack provides a complete framework for developing full-stack JavaScript apps.
Using the TextEncoder and TextDecoder Interfaces
The TextEncoder and TextDecoder interfaces are part of the Web Encoding API. They provide a standardized way to convert strings into bytes. You can use them together with the btoa() and atob() functions to encode and decode strings that contain non-ASCII characters, such as emojis, non-Latin scripts, or accented letters.
For example, you can use TextEncoder to convert JavaScript UTF-16 strings into UTF-8 bytes, and then apply the btoa() function to encode them to Base64:
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const text = "Pretty Picture 🌄";
const bytes = encoder.encode(text);
const base64 = btoa(String.fromCharCode(...bytes));
console.log(base64);
In this example, TextEncoder converts the Pretty Picture 🌄 string into a sequence of UTF-8 bytes. These bytes are then passed to btoa(), which produces a Base64-encoded string:
UHJldHR5IFBpY3R1cmUg8J+QpA==
To decode the string back into readable text, reverse the process using atob() and the TextDecoder interface:
const binary = Uint8Array.from(atob(base64), c => c.charCodeAt(0));
const decodedText = decoder.decode(binary);
console.log(decodedText);
The atob() function converts the Base64 string back into binary data, which TextDecoder reconstructs into a UTF-8 array and converts to readable text:
Pretty Picture 🌄
TextEncoder and TextDecoder are supported in most browsers and in Node.js. Use them when you want to ensure your code can handle any character set, encoding, or language, across different client- and server-side environments.
Conclusion
You now know how to use JavaScript's native functions to turn binary data into text and convert it back again when Base64-encoded data is received.
If you are building dynamic web apps, consider using Docker to build Node.js apps and create isolated, reproducible test environments.



