base64-js vs js-base64 vs base-64 vs btoa
Encoding Binary Data and Strings in JavaScript
base64-jsjs-base64base-64btoaSimilar Packages:

Encoding Binary Data and Strings in JavaScript

These libraries provide solutions for Base64 encoding and decoding in JavaScript environments. While browsers and modern Node.js include native btoa and atob functions, they fail when handling Unicode characters (like emojis or non-English text). base-64, base64-js, and js-base64 offer robust alternatives that handle UTF-8 correctly, while the btoa npm package serves primarily as a polyfill for older environments. Choosing the right tool depends on whether you are processing text strings or raw binary data like files.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
base64-js159,885,8488799.62 kB66 years agoMIT
js-base6420,843,7884,36238.4 kB11a month agoBSD-3-Clause
base-647,452,606520-126 years agoMIT
btoa0---9 years ago(MIT OR Apache-2.0)

Encoding Data in JavaScript: base-64 vs base64-js vs btoa vs js-base64

Handling Base64 encoding in JavaScript seems simple until you encounter Unicode characters. The native btoa function breaks when given emojis or non-ASCII text. This comparison looks at four npm packages that address this problem — each with a different focus on strings, binary data, or compatibility.

📝 Text Encoding: Handling Unicode Correctly

The most common mistake is using native btoa for user input. It expects Latin1 strings. If you pass a emoji, it throws an error. These packages solve that by converting text to UTF-8 bytes first.

base-64 handles UTF-8 strings automatically. It is lightweight and focused purely on string conversion.

import * as base64 from 'base-64';

const text = 'Hello 🌍';
const encoded = base64.encode(text);
const decoded = base64.decode(encoded);

console.log(decoded); // 'Hello 🌍'

js-base64 also handles UTF-8 strings and provides a familiar static class interface. It is widely used in larger applications.

import { Base64 } from 'js-base64';

const text = 'Hello 🌍';
const encoded = Base64.encode(text);
const decoded = Base64.decode(encoded);

console.log(decoded); // 'Hello 🌍'

btoa (npm package) mimics the native browser function. It does not fix Unicode issues by itself. You still need to escape the string manually.

import btoa from 'btoa';

const text = 'Hello 🌍';
// This will throw an error or produce garbage without manual UTF-8 escaping
// const encoded = btoa(unescape(encodeURIComponent(text))); 

base64-js does not accept strings directly. It works with binary arrays. You must convert the string to bytes first.

import * as base64js from 'base64-js';

const text = 'Hello 🌍';
const uint8 = new TextEncoder().encode(text);
const encoded = base64js.fromUint8Array(uint8);

// Decoding requires reversing the process
const decodedUint8 = base64js.toUint8Array(encoded);
const decoded = new TextDecoder().decode(decodedUint8);

🗂️ Binary Data: Uint8Array and Buffers

When working with files, images, or network packets, you often deal with binary data rather than text. This is where the packages diverge significantly.

base64-js is built specifically for this. It converts between Uint8Array and Base64 strings efficiently.

import * as base64js from 'base64-js';

const binaryData = new Uint8Array([72, 101, 108, 108, 111]); // 'Hello'
const base64String = base64js.fromUint8Array(binaryData);
const restoredBinary = base64js.toUint8Array(base64String);

base-64 works primarily with strings. To use it with binary data, you must convert bytes to a string first, which adds overhead.

import * as base64 from 'base-64';

// Requires manual conversion to string representation of bytes
// Not ideal for raw binary workflows

js-base64 focuses on strings. While it can handle binary data represented as strings, it is not optimized for raw Uint8Array manipulation like base64-js.

import { Base64 } from 'js-base64';

// Best for string payloads, not raw binary buffers
const encoded = Base64.encode('binary-like-string');

btoa expects a "binary string" where each character represents a byte. Passing real binary data requires careful mapping.

import btoa from 'btoa';

// Only works if input is a Latin1 string representing bytes
// Not safe for arbitrary Uint8Array without conversion

🔗 URL Safety: Special Characters

Standard Base64 uses + and /, which have special meanings in URLs. If you put Base64 in a URL query parameter, it might break. You need URL-safe Base64 (using - and _).

js-base64 has built-in methods for this. It is the strongest choice for URL parameters.

import { Base64 } from 'js-base64';

const safeEncoded = Base64.encodeURI('data+with/special');
// Uses - and _ instead of + and /

base-64 does not have a dedicated URL-safe method. You must replace characters manually.

import * as base64 from 'base-64';

const encoded = base64.encode('data+with/special');
const urlSafe = encoded.replace(/\+/g, '-').replace(/\//g, '_');

base64-js produces standard Base64. You must implement URL-safe logic yourself if needed.

import * as base64js from 'base64-js';

const encoded = base64js.fromUint8Array(data);
const urlSafe = encoded.replace(/\+/g, '-').replace(/\//g, '_');

btoa produces standard Base64. No URL-safe support included.

import btoa from 'btoa';

const encoded = btoa('data');
// Manual replacement required for URL safety

⚠️ Maintenance and Environment Support

Knowing where these packages run helps avoid build errors.

btoa is largely obsolete. Modern Node.js (v16+) and all browsers have global btoa. The npm package is only useful for very old Node versions.

// Modern Node.js or Browser
const encoded = btoa('text'); // Native global available

base-64 works everywhere. It has no dependencies and is small.

// Works in Node, Browser, Web Workers
import * as base64 from 'base-64';

js-base64 works everywhere. It is slightly larger but offers more features.

// Works in Node, Browser, TypeScript projects
import { Base64 } from 'js-base64';

base64-js works everywhere. It is the standard for binary conversion.

// Works in Node, Browser, React Native
import * as base64js from 'base64-js';

📊 Summary Table

Featurebase-64base64-jsbtoa (npm)js-base64
Unicode Support✅ Yes✅ Yes (via Uint8)❌ No (Manual)✅ Yes
Input TypeStringUint8ArrayStringString
URL Safe❌ Manual❌ Manual❌ Manual✅ Built-in
Binary Focus❌ Low✅ High❌ Low❌ Low
Status✅ Active✅ Active⚠️ Legacy✅ Active

💡 Final Recommendation

For most frontend developers, the choice comes down to what you are encoding.

If you are encoding text strings (like JSON payloads or user input) and need Unicode support, use base-64 for simplicity or js-base64 if you need URL-safe variants. They handle the UTF-8 conversion automatically, which saves you from subtle bugs.

If you are encoding binary files (like images or blobs) and already have a Uint8Array, use base64-js. It is optimized for byte manipulation and avoids unnecessary string conversions.

Avoid the btoa npm package. It solves a problem (missing global function) that no longer exists in modern environments, and it does not fix the Unicode issue that actually matters.

Final Thought: Native APIs are improving, but for cross-platform Unicode safety, a dedicated library is still the safest bet for production apps.

How to Choose: base64-js vs js-base64 vs base-64 vs btoa

  • base64-js:

    Choose base64-js if you are working directly with binary data such as Uint8Array or Buffer objects. It is the best fit for low-level operations like file processing, image manipulation, or WebSocket binary frames where string encoding is not the primary goal.

  • js-base64:

    Choose js-base64 if you need advanced features like URL-safe encoding or comprehensive Unicode support out of the box. It is well-suited for complex applications that require encoding data for URLs, cookies, or transmission over protocols that restrict standard Base64 characters.

  • base-64:

    Choose base-64 if you need a lightweight, dependency-free solution for encoding UTF-8 strings in both browser and Node.js. It is ideal for simple text encoding tasks where you want to avoid the Unicode pitfalls of the native btoa function without adding a heavy library.

  • btoa:

    Avoid the btoa npm package in new projects. It is essentially a polyfill for the native browser function and does not solve Unicode issues on its own. Modern Node.js versions and all browsers already include global btoa, making this package redundant for most use cases.

README for base64-js

base64-js

base64-js does basic base64 encoding/decoding in pure JS.

build status

Many browsers already have base64 encoding/decoding functionality, but it is for text data, not all-purpose binary data.

Sometimes encoding/decoding binary data in the browser is useful, and that is what this module does.

install

With npm do:

npm install base64-js and var base64js = require('base64-js')

For use in web browsers do:

<script src="base64js.min.js"></script>

Get supported base64-js with the Tidelift Subscription

methods

base64js has three exposed functions, byteLength, toByteArray and fromByteArray, which both take a single argument.

  • byteLength - Takes a base64 string and returns length of byte array
  • toByteArray - Takes a base64 string and returns a byte array
  • fromByteArray - Takes a byte array and returns a base64 string

license

MIT