If your data may contain multi-byte sequences (not a plain ASCII sequence) and your browser has TextDecoder, then you should use that to decode your data (specify the required encoding for the TextDecoder):

var u8 = new Uint8Array([65, 66, 67, 68]);
var decoder = new TextDecoder('utf8');
var b64encoded = btoa(decoder.decode(u8));

If you need to support browsers that do not have TextDecoder (currently just IE and Edge), then the best option is to use a TextDecoder polyfill.

If your data contains plain ASCII (not multibyte Unicode/UTF-8) then there is a simple alternative using String.fromCharCode that should be fairly universally supported:

var ascii = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(String.fromCharCode.apply(null, ascii));

And to decode the base64 string back to a Uint8Array:

var u8_2 = new Uint8Array(atob(b64encoded).split("").map(function(c) {
    return c.charCodeAt(0); }));

If you have very large array buffers then the apply may fail with Maximum call stack size exceeded and you may need to chunk the buffer (based on the one posted by @RohitSengar). Again, note that this is only correct if your buffer only contains non-multibyte ASCII characters:

function Uint8ToString(u8a){
  var CHUNK_SZ = 0x8000;
  var c = [];
  for (var i=0; i < u8a.length; i+=CHUNK_SZ) {
    c.push(String.fromCharCode.apply(null, u8a.subarray(i, i+CHUNK_SZ)));
  }
  return c.join("");
}
// Usage
var u8 = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(Uint8ToString(u8));
Answer from kanaka on Stack Overflow
Top answer
1 of 16
160

If your data may contain multi-byte sequences (not a plain ASCII sequence) and your browser has TextDecoder, then you should use that to decode your data (specify the required encoding for the TextDecoder):

var u8 = new Uint8Array([65, 66, 67, 68]);
var decoder = new TextDecoder('utf8');
var b64encoded = btoa(decoder.decode(u8));

If you need to support browsers that do not have TextDecoder (currently just IE and Edge), then the best option is to use a TextDecoder polyfill.

If your data contains plain ASCII (not multibyte Unicode/UTF-8) then there is a simple alternative using String.fromCharCode that should be fairly universally supported:

var ascii = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(String.fromCharCode.apply(null, ascii));

And to decode the base64 string back to a Uint8Array:

var u8_2 = new Uint8Array(atob(b64encoded).split("").map(function(c) {
    return c.charCodeAt(0); }));

If you have very large array buffers then the apply may fail with Maximum call stack size exceeded and you may need to chunk the buffer (based on the one posted by @RohitSengar). Again, note that this is only correct if your buffer only contains non-multibyte ASCII characters:

function Uint8ToString(u8a){
  var CHUNK_SZ = 0x8000;
  var c = [];
  for (var i=0; i < u8a.length; i+=CHUNK_SZ) {
    c.push(String.fromCharCode.apply(null, u8a.subarray(i, i+CHUNK_SZ)));
  }
  return c.join("");
}
// Usage
var u8 = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(Uint8ToString(u8));
2 of 16
117

If you are using Node.js then you can use this code to convert Uint8Array to base64

var u8 = new Uint8Array([65, 66, 67, 68]);
var b64 = Buffer.from(u8).toString('base64');
🌐
npm
npmjs.com › package › uint8-to-base64
uint8-to-base64 - npm
import {encode, decode} from 'uint8-to-base64'; // const {encode, decode} = require('uint8-to-base64'); const utf8Binary = new Uint8Array(anyArrayBuffer); // encode converts Uint8Array instances to base64 strings const encoded = encode(utf8Binary); ...
      » npm install uint8-to-base64
    
Published   Jun 23, 2025
Version   0.2.1
🌐
GitHub
github.com › WebReflection › uint8-to-base64
GitHub - WebReflection/uint8-to-base64: A safe Uint8Array to base64 string converter · GitHub
import {encode, decode} from 'uint8-to-base64'; // const {encode, decode} = require('uint8-to-base64'); const utf8Binary = new Uint8Array(anyArrayBuffer); // encode converts Uint8Array instances to base64 strings const encoded = encode(utf8Binary); ...
Author   WebReflection
🌐
GitHub
github.com › tc39 › proposal-arraybuffer-base64
GitHub - tc39/proposal-arraybuffer-base64: TC39 proposal for Uint8Array<->base64/hex · GitHub
So despite fitting with the type signature of TextEncoder/TextDecoder, base64 encoding and decoding is not a conceptually appropriate thing for those APIs to do. That's also been the consensus when it's come up previously. Uint8Arrays can be partial views of an underlying buffer, so you can create such a view and invoke .toBase64 on it.
Starred by 281 users
Forked by 14 users
Languages   HTML 37.3% | JavaScript 33.7% | CSS 29.0%
🌐
Bun
bun.com › modules › globals › uint8array › tobase64
Uint8Array.toBase64 method | globals module | Bun
January 5, 2026 - toBase64( options?: { alphabet: 'base64' | 'base64url'; omitPadding: boolean } ): string; Convert the Uint8Array to a base64 encoded string ·
🌐
GitHub
github.com › streamich › uint8-to-b64
GitHub - streamich/uint8-to-b64: Isomorphic Uint8Array conversion to Base64 string and back for browser and Node.js · GitHub
Isomorphic Uint8Array conversion to Base64 string and back for browser and Node.js - streamich/uint8-to-b64
Author   streamich
🌐
npm
npmjs.com › package › uint8-to-b64
uint8-to-b64 - npm
Latest version: 1.0.2, last published: 5 years ago. Start using uint8-to-b64 in your project by running `npm i uint8-to-b64`. There are 1 other projects in the npm registry using uint8-to-b64.
      » npm install uint8-to-b64
    
Published   Mar 30, 2021
Version   1.0.2
Find elsewhere
🌐
TC39
tc39.es › proposal-arraybuffer-base64
Proposed Support for Base64 in JavaScript
The base64 encoder allows omitting padding by specifying omitPadding: true. The default is to include padding. The hex methods do not have any options. let array = new Uint8Array([251, 255, 191]); console.log(array.toBase64({ alphabet: 'base64' })); // '+/+/' console.log(array.toBase64({ alphabet: 'base64url' })); // '-_-_' console.log(Uint8Array.fromBase64('SGVsbG8g\nV29ybG R')); // works, despite whitespace, missing padding, and non-zero overflow bits try { Uint8Array.fromBase64('SGVsbG8gV29ybGR=', { lastChunkHandling: 'strict' }); } catch { console.log('with lastChunkHandling: "strict", ove
🌐
TC39
tc39.es › proposal-arraybuffer-base64 › spec
Uint8Array to/from base64
Set index to index + 1. Return index. The abstract operation DecodeBase64Chunk takes argument chunk (a string) and optional argument throwOnExtraBits (a boolean) and returns either a ... The standard base64 alphabet is the String whose elements are the code units corresponding to every letter and number in the Unicode Basic Latin block along with
🌐
Cloudflare Community
community.cloudflare.com › developers › cloudflare workers
Uint8Array to Base64 in Workers - Cloudflare Workers - Cloudflare Community
March 29, 2022 - I am using some of the web crypto “techniques” to encrypt data I send to the client… so I can store it in a cache and use it on subsequent requests. And for added security. I have my encrypted data… but it’s an ArrayBuffer… Uint8Array. I’m struggling to convert it to base64 so I can send it back to the client.
🌐
Coolaj86
coolaj86.com › articles › typedarray-buffer-to-base64-in-javascript
Convert a TypedArray Buffer to Base64 in JavaScript
June 26, 2015 - // "I ½ ♥ 💩"; var arr = [73, 32, 194, 189, 32, 226, 153, 165, 32, 240, 159, 146, 169]; var data = new Uint8Array(arr); var base64 = bufferToBase64(data); // "SSDCvSDimaUg8J+SqQ=="
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Global_Objects › Uint8Array › fromBase64
Uint8Array.fromBase64() - JavaScript - MDN Web Docs
The last chunk must be exactly 4 characters long with padding = characters. Furthermore, overflow bits (trailing bits from the last base64 character that don't represent any data) must be 0. The last chunk is decoded and appended to the result.
🌐
GitHub
github.com › sindresorhus › uint8array-extras
GitHub - sindresorhus/uint8array-extras: Useful utilities for working with Uint8Array (and Buffer) · GitHub
Specify {urlSafe: true} to get a Base64URL-encoded string. ... import {uint8ArrayToBase64} from 'uint8array-extras'; const byteArray = new Uint8Array([72, 101, 108, 108, 111]); console.log(uint8ArrayToBase64(byteArray)); //=> 'SGVsbG8='
Author   sindresorhus
🌐
Deno
docs.deno.com › deno docs › examples › hex and base64 encoding
Hex and base64 encoding | Deno Docs
const urlSafe = bytes.toBase64({ alphabet: "base64url" }); console.log(urlSafe); // c29tZXN0cmluZ3RvZW5jb2Rl · Hex encoding works the same way, with toHex and fromHex. const hexEncoded = bytes.toHex(); console.log(hexEncoded); // 736f6d65737472696e67746f656e636f6465 · And back again. const hexDecoded = Uint8Array.fromHex(hexEncoded); console.log(new TextDecoder().decode(hexDecoded)); // somestringtoencode
🌐
Vectorstores
vectorstores.org › api › functions › uint8arraytobase64
uint8ArrayToBase64 | vectorstores Documentation
Converts a Uint8Array to a base64 string. For large arrays, it processes the data in chunks to avoid memory issues.
🌐
GitHub
github.com › MrPropre › base64-u8array-arraybuffer
GitHub - MrPropre/base64-u8array-arraybuffer: 📦 A simple, lightweight, and efficient JavaScript library to manage encoding/decoding between base64 data, Uint8Arrays, and ArrayBuffers
import { base64ToArrayBuffer } from 'base64-u8array-arraybuffer' const buffer = base64ToArrayBuffer('base64 string here') ... Note ES Module syntax also works in modern browsers. You just need to add type="module" to your <script> tag.
Author   MrPropre
🌐
Cheminfo
cheminfo.github.io › uint8-base64
uint8-base64
import { encode } from 'uint8-base64'; const bytes = new Uint8Array(256 * 1024 * 1024).map((_, i) => Math.floor(Math.random() * 256), ); console.time('base64'); const base64 = encode(bytes); const string = new TextDecoder('utf8').decode(base64); console.timeEnd('base64'); console.log(string.slice(0, 100)); Copy · This code takes 330ms on my MacBook pro M4 to encode 256Mb of data.