npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@httpx/encode

v0.4.0

Published

Base encodings, ie base64...

Readme

@httpx/encode

npm changelog codecov bundles node browserslist downloads license

Base64 encoding optimized for performance and correctness. 1.5x-7x faster on decode() than js-base64 and up to 2x on encode(). Same options and validation rules as the native Uint8Array.fromBase64 on every runtime. Less than 400b on bun and deno.

Install

$ npm install @httpx/encode
$ yarn add @httpx/encode
$ pnpm add @httpx/encode

Features

  • 🚀  Fast: picks the fastest implementation for the runtime (native, Buffer or optimized js).
  • 📏  Same options as the native Uint8Array.fromBase64() / toBase64(): base64url, padding, lastChunkHandling.
  • 🌍  Unicode safe: utf-8 text, emoji, BOM and lone surrogates (see notes).
  • 🦆  Works with text (encode / decode) and bytes (fromUint8Array / toUint8Array).
  • 🛡️  Throws on invalid input instead of silently returning corrupted data.
  • 📐  Lightweight (starts at ~390B)
  • 🛡️  Tested on node 22-26, browser, bun, cloudflare and runtime/edge.
  • 🗝️  Available in ESM only.

Documentation

👉 Official website or GitHub Readme

Base64

Base64 encodes and decodes base64 / base64url. Text is always converted to and from utf-8. The implementation is selected once, when the module is loaded (see implementations).

API

| Method | Description | | --- | --- | | encode(text, options?): string | Encode a string (utf-8) to base64 | | decode(base64, options?): string | Decode a base64 string to a string (utf-8) | | fromUint8Array(bytes, options?): string | Encode bytes to base64 | | toUint8Array(base64, options?): Uint8Array | Decode a base64 string to bytes |

Usage

// bundle size: ~390B (bun, deno), ~1.4kB (browser)
import { Base64 } from "@httpx/encode";

// 👇 Text (utf-8)
Base64.encode("Hello 🌸"); // 👈 "SGVsbG8g8J+MuA=="
Base64.decode("SGVsbG8g8J+MuA=="); // 👈 "Hello 🌸"

// 👇 Bytes
Base64.fromUint8Array(new Uint8Array([0xfb, 0xff])); // 👈 "+/8="
Base64.toUint8Array("+/8="); // 👈 Uint8Array [0xfb, 0xff]

// 👇 base64url, ie: urls, cookies, jwt...
Base64.encode("Hello 🌸", { alphabet: "base64url", omitPadding: true }); // 👈 "SGVsbG8g8J-MuA"
Base64.decode("SGVsbG8g8J-MuA"); // 👈 "Hello 🌸" (both alphabets accepted by default)

Base64.decode()

Decodes a base64 or base64url string to text. Ascii whitespace (ie: line breaks) is ignored, the padding is optional unless lastChunkHandling is "strict".

Base64.decode("8J+MuA=="); // 👈 "🌸"
Base64.decode("8J-MuA"); // 👈 "🌸" (base64url, no padding)
Base64.decode("8J+M\nuA==\n"); // 👈 "🌸" (whitespace ignored)

Base64.decode("8J+MuA==", { alphabet: "base64url" }); // 👈 throws ('+' not allowed)
Base64.decode("Zm9vYg", { lastChunkHandling: "strict" }); // 👈 throws (missing padding)
Base64.decode("Zm9vYg", { lastChunkHandling: "stop-before-partial" }); // 👈 "foo"

Base64.decode("/w=="); // 👈 "�" (0xff is not valid utf-8)
Base64.decode("/w==", { fatal: true }); // 👈 throws

Base64.toUint8Array()

Decodes a base64 or base64url string to bytes. Always returns a plain Uint8Array that owns its memory (never a Buffer from node's shared pool).

Base64.toUint8Array("+/8="); // 👈 Uint8Array [0xfb, 0xff]
Base64.toUint8Array("-_8"); // 👈 Uint8Array [0xfb, 0xff]
Base64.toUint8Array("-_8=", { alphabet: "base64" }); // 👈 throws ('-' not allowed)

Options

Encode options, used by encode() and fromUint8Array(), same as Uint8Array.prototype.toBase64():

| Option | Default | Description | | --- | --- | --- | | alphabet | "base64" | "base64" uses + and / (RFC 4648 §4), "base64url" uses - and _ (RFC 4648 §5) | | omitPadding | false | Omit the trailing = padding characters |

Decode options, used by decode() and toUint8Array(), same as Uint8Array.fromBase64():

| Option | Default | Description | | --- | --- | --- | | alphabet | both | Restrict to "base64" or "base64url". When not set, both alphabets are accepted (even mixed) | | lastChunkHandling | "loose" | "loose", "strict" or "stop-before-partial", see below | | fatal | false | decode() only. Throw when the decoded bytes are not valid utf-8 instead of replacing them with U+FFFD (�), see TextDecoder.fatal |

[!NOTE] Unlike Uint8Array.fromBase64() that defaults to "base64", the alphabet is not restricted when the option is not set.

How lastChunkHandling handles a last chunk of less than 4 characters:

| Input | "loose" | "strict" | "stop-before-partial" | | --- | --- | --- | --- | | "Zm9vYg==" | "foob" | "foob" | "foob" | | "Zm9vYg" | "foob" | throws (missing padding) | "foo" | | "Zm9vYg=" | throws | throws | "foo" | | "Zm9vY" | throws | throws | "foo" | | "Zh==" | "f" | throws (non-zero bits) | "f" |

Errors

Invalid input throws an Error, the original error (if any) is available in error.cause.

| Message starts with | When | | --- | --- | | Invalid Base64 input | Character outside of the alphabet, misplaced or extra =, dangling character, lastChunkHandling: "strict" | | Invalid UTF-8 | decode() with { fatal: true } and the decoded bytes are not valid utf-8 |

Base64.decode("SGVsbG8*"); // 👈 throws (invalid character)
Base64.decode("SGV$bG8="); // 👈 throws (node's Buffer silently returns corrupted data)
Base64.decode("SGVsbG8=="); // 👈 throws (extra padding)
Base64.decode("SGVsb"); // 👈 throws (dangling character)

Implementations

import { Base64 } from "@httpx/encode" resolves to the fastest implementation for the runtime, based on the benchmarks:

| Runtime | Implementation | | --- | --- | | node 25+, bun, deno, chrome 140+, firefox 133+, safari 18.2+ | native Uint8Array.fromBase64() / toBase64() | | node 22 - 24 | Buffer | | older browsers, edge runtimes without the native api | optimized js encode, atob() based decode |

Each implementation can also be imported directly. They all share the same api and behaviour.

import { Base64Atob } from "@httpx/encode/base64/base64.atob"; // 👈 atob() / btoa()
import { Base64Node20 } from "@httpx/encode/base64/base64.node20"; // 👈 Buffer, native on node 25+
import { Base64Purejs } from "@httpx/encode/base64/base64.purejs"; // 👈 no runtime dependency
import { Base64Uint8Array } from "@httpx/encode/base64/base64.uint8array"; // 👈 native, requires Uint8Array.fromBase64

Notes

Text vs binary

encode() / decode() convert to and from utf-8 text, which is lossy for arbitrary bytes. Use fromUint8Array() / toUint8Array() for binary data (images, hashes, keys...).

Base64.encode(Base64.decode("/w==")); // 👈 "77+9" ❌ (0xff became U+FFFD)
Base64.fromUint8Array(Base64.toUint8Array("/w==")); // 👈 "/w==" ✅

Unicode

Compared to a raw btoa() / atob():

| Input | btoa() / atob() | Base64 | | --- | --- | --- | | "🌸" | throws InvalidCharacterError | "8J+MuA==" | | "é" | "6Q==" (latin1, silently differs) | "w6k=" (utf-8) | | decode "w6k=" | "é" (mojibake) | "é" | | leading BOM (U+FEFF) | throws | preserved (encode and decode) | | lone surrogate (U+D800) | throws | encoded as U+FFFD, like TextEncoder | | ~1MB input | String.fromCharCode(...bytes) overflows the stack | ✅ |

Benchmarks

Performance is continuously monitored thanks to codspeed.io.

CodSpeed Badge

Node 26.10

 RUN  v5.0.4 /Users/sebastien/github/httpx/packages/encode

 ✓ |bench| bench/base64.bench.ts > Base64 implementations > encode (original size: 11.2 kB) 5127ms
   name                                                hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode node20 (Buffer).encode()      209,819.44  0.0045  0.0812  0.0048  0.0048  0.0063  0.0067  0.0226  ±0.12%   207612   fastest
   @httpx/encode uint8array (native).encode()  209,467.86  0.0044  0.1748  0.0048  0.0048  0.0064  0.0069  0.0225  ±0.13%   207038
   @httpx/encode purejs.encode()                73,449.47  0.0129  0.1810  0.0137  0.0136  0.0180  0.0208  0.0378  ±0.13%    72913
   @httpx/encode atob.encode()                  33,517.66  0.0282  0.9854  0.0301  0.0298  0.0411  0.0750  0.0904  ±0.25%    33178   slowest
 ✓ |bench| bench/base64.bench.ts > Base64 implementations > decode (original size: 11.2 kB) 5077ms
   name                                                hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode uint8array (native).decode()  128,115.64  0.0058  0.1110  0.0079  0.0082  0.0104  0.0117  0.0294  ±0.13%   126368   fastest
   @httpx/encode node20 (Buffer).decode()      125,955.89  0.0058  0.1082  0.0081  0.0083  0.0107  0.0119  0.0295  ±0.13%   124215
   @httpx/encode atob.decode()                  37,204.08  0.0223  0.1559  0.0271  0.0279  0.0348  0.0384  0.0833  ±0.13%    36878
   @httpx/encode purejs.decode()                27,869.73  0.0322  0.7858  0.0361  0.0370  0.0471  0.0530  0.0725  ±0.19%    27671   slowest
 ✓ |bench| bench/base64.bench.ts > Base64 implementations > fromUint8Array (original size: 15.2 kB) 5670ms
   name                                                          hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode uint8array (native).fromUint8Array()  1,464,122.25  0.0005  0.0849  0.0007  0.0007  0.0009  0.0010  0.0020  ±0.22%  1399013   fastest
   @httpx/encode node20 (Buffer).fromUint8Array()      1,463,755.15  0.0005  0.0720  0.0007  0.0007  0.0009  0.0010  0.0020  ±0.22%  1398909
   @httpx/encode purejs.fromUint8Array()                 106,873.97  0.0089  0.3757  0.0094  0.0094  0.0123  0.0131  0.0301  ±0.14%   105972
   @httpx/encode atob.fromUint8Array()                    39,362.38  0.0241  1.2913  0.0257  0.0254  0.0349  0.0729  0.0834  ±0.30%    38899   slowest
 ✓ |bench| bench/base64.bench.ts > Base64 implementations > toUint8Array (original size: 15.2 kB) 5272ms
   name                                                      hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode uint8array (native).toUint8Array()  392,692.06  0.0021  0.9078  0.0027  0.0026  0.0032  0.0034  0.0087  ±0.86%   374841   fastest
   @httpx/encode node20 (Buffer).toUint8Array()      393,620.82  0.0021  0.8117  0.0027  0.0026  0.0032  0.0033  0.0085  ±0.93%   374397
   @httpx/encode atob.toUint8Array()                  50,849.37  0.0172  0.1604  0.0199  0.0218  0.0262  0.0292  0.0432  ±0.13%    50223
   @httpx/encode purejs.toUint8Array()                32,101.48  0.0281  0.9966  0.0315  0.0321  0.0390  0.0430  0.0549  ±0.43%    31721   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > encode (original size: 11.2 kB) 3860ms
   name                                            hz     min     max    mean     p75     p99    p995    p999     rme  samples
   npm:js-base64 encode()                  212,167.66  0.0044  0.0889  0.0048  0.0048  0.0062  0.0066  0.0223  ±0.12%   209924   fastest
   @httpx/encode Base64.encode()           210,316.41  0.0044  0.1482  0.0048  0.0048  0.0063  0.0067  0.0226  ±0.13%   207972
   npm:uint8array-extras stringToBase64()   15,953.24  0.0608  0.1523  0.0630  0.0622  0.0853  0.1119  0.1210  ±0.13%    15879   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > decode (original size: 11.2 kB) 3796ms
   name                                            hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode Base64.decode()           125,360.36  0.0058  0.1223  0.0081  0.0084  0.0105  0.0118  0.0295  ±0.13%   123676   fastest
   npm:js-base64 decode()                   47,029.92  0.0179  0.7439  0.0214  0.0218  0.0280  0.0298  0.0484  ±0.18%    46677
   npm:uint8array-extras base64ToString()    2,631.16  0.3635  0.7737  0.3812  0.3806  0.4814  0.5002  0.5513  ±0.24%     2624   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > fromUint8Array (original size: 15.2 kB) 4441ms
   name                                                  hz     min     max    mean     p75     p99    p995    p999     rme  samples
   npm:js-base64 fromUint8Array()              1,498,730.61  0.0005  0.0966  0.0007  0.0007  0.0009  0.0010  0.0021  ±0.23%  1430470   fastest
   @httpx/encode Base64.fromUint8Array()       1,496,873.02  0.0005  0.1265  0.0007  0.0007  0.0009  0.0010  0.0024  ±0.23%  1428573
   npm:uint8array-extras uint8ArrayToBase64()     17,264.93  0.0567  7.9747  0.0588  0.0574  0.0805  0.1033  0.1140  ±1.66%    17000   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > toUint8Array (original size: 15.2 kB) 3897ms
   name                                                hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode Base64.toUint8Array()         406,184.13  0.0019  0.9257  0.0026  0.0026  0.0033  0.0037  0.0097  ±0.90%   383475   fastest
   npm:js-base64 toUint8Array()                 53,658.84  0.0163  0.8963  0.0190  0.0191  0.0250  0.0292  0.0487  ±0.55%    52761
   npm:uint8array-extras base64ToUint8Array()    2,704.57  0.3570  0.5255  0.3706  0.3714  0.4618  0.4730  0.4980  ±0.20%     2699   slowest

Bun 1.4.3

 RUN  v5.0.4 /Users/sebastien/github/httpx/packages/encode

 ✓ |bench| bench/base64.bench.ts > Base64 implementations > encode (original size: 11.2 kB) 5110ms
   name                                                hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode uint8array (native).encode()  206,094.03  0.0044  0.5664  0.0050  0.0049  0.0080  0.0113  0.0204  ±0.57%   199966   fastest
   @httpx/encode node20 (Buffer).encode()      203,988.82  0.0044  0.6793  0.0051  0.0050  0.0080  0.0116  0.0209  ±0.58%   197972
   @httpx/encode purejs.encode()                91,362.35  0.0101  0.6279  0.0112  0.0109  0.0169  0.0193  0.0321  ±0.52%    89428
   @httpx/encode atob.encode()                  49,976.67  0.0190  0.8020  0.0204  0.0199  0.0297  0.0373  0.0465  ±0.53%    49115   slowest
 ✓ |bench| bench/base64.bench.ts > Base64 implementations > decode (original size: 11.2 kB) 5080ms
   name                                                hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode uint8array (native).decode()  135,872.28  0.0053  0.6410  0.0076  0.0080  0.0117  0.0142  0.0361  ±0.53%   130974   fastest
   @httpx/encode node20 (Buffer).decode()      132,237.01  0.0052  1.1615  0.0079  0.0082  0.0111  0.0125  0.0340  ±0.77%   127059
   @httpx/encode purejs.decode()                54,290.21  0.0164  0.6461  0.0186  0.0188  0.0253  0.0280  0.0492  ±0.36%    53623
   @httpx/encode atob.decode()                  52,561.19  0.0156  0.5963  0.0194  0.0198  0.0265  0.0326  0.0461  ±0.41%    51679   slowest
 ✓ |bench| bench/base64.bench.ts > Base64 implementations > fromUint8Array (original size: 15.2 kB) 5432ms
   name                                                          hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode node20 (Buffer).fromUint8Array()      1,249,495.76  0.0006  0.6025  0.0009  0.0008  0.0012  0.0013  0.0093  ±0.80%  1161525   fastest
   @httpx/encode uint8array (native).fromUint8Array()  1,243,892.07  0.0006  0.6304  0.0009  0.0008  0.0013  0.0016  0.0092  ±0.81%  1151997
   @httpx/encode purejs.fromUint8Array()                 146,825.57  0.0061  0.9629  0.0070  0.0068  0.0112  0.0147  0.0278  ±0.63%   142204
   @httpx/encode atob.fromUint8Array()                    63,736.44  0.0149  0.6357  0.0159  0.0156  0.0241  0.0324  0.0388  ±0.43%    62726   slowest
 ✓ |bench| bench/base64.bench.ts > Base64 implementations > toUint8Array (original size: 15.2 kB) 5226ms
   name                                                      hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode node20 (Buffer).toUint8Array()      498,884.26  0.0017  0.6283  0.0021  0.0021  0.0028  0.0053  0.0133  ±0.61%   475996   fastest
   @httpx/encode uint8array (native).toUint8Array()  482,012.43  0.0017  0.8528  0.0022  0.0023  0.0033  0.0065  0.0171  ±0.74%   452786
   @httpx/encode atob.toUint8Array()                  79,003.11  0.0118  0.6316  0.0129  0.0125  0.0193  0.0233  0.0346  ±0.41%    77775
   @httpx/encode purejs.toUint8Array()                72,061.20  0.0128  0.7634  0.0140  0.0141  0.0198  0.0248  0.0311  ±0.34%    71320   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > encode (original size: 11.2 kB) 3841ms
   name                                            hz     min     max    mean     p75     p99    p995    p999     rme  samples
   npm:js-base64 encode()                  204,033.85  0.0044  0.6682  0.0051  0.0049  0.0085  0.0124  0.0216  ±0.65%   196710   fastest
   @httpx/encode Base64.encode()           202,358.39  0.0045  0.6683  0.0051  0.0050  0.0087  0.0125  0.0235  ±0.66%   194786
   npm:uint8array-extras stringToBase64()   42,083.16  0.0220  0.8210  0.0241  0.0237  0.0337  0.0383  0.0495  ±0.49%    41496   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > decode (original size: 11.2 kB) 3800ms
   name                                            hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode Base64.decode()           130,439.43  0.0054  1.0410  0.0080  0.0083  0.0126  0.0168  0.0370  ±0.86%   124441   fastest
   npm:js-base64 decode()                   73,574.14  0.0095  0.8978  0.0143  0.0163  0.0238  0.0293  0.0466  ±0.50%    69875
   npm:uint8array-extras base64ToString()   21,209.53  0.0408  0.7774  0.0481  0.0487  0.0651  0.0723  0.5821  ±0.59%    20775   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > fromUint8Array (original size: 15.2 kB) 4131ms
   name                                                  hz     min     max    mean     p75     p99    p995    p999     rme  samples
   npm:js-base64 fromUint8Array()              1,237,376.06  0.0005  0.7423  0.0009  0.0008  0.0013  0.0015  0.0102  ±0.89%  1138126   fastest
   @httpx/encode Base64.fromUint8Array()       1,224,874.00  0.0006  0.8135  0.0009  0.0008  0.0015  0.0021  0.0120  ±1.03%  1104981
   npm:uint8array-extras uint8ArrayToBase64()     50,881.21  0.0189  0.5976  0.0199  0.0194  0.0289  0.0327  0.0424  ±0.34%    50283   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > toUint8Array (original size: 15.2 kB) 3890ms
   name                                                hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode Base64.toUint8Array()         501,423.52  0.0017  0.9145  0.0021  0.0021  0.0033  0.0061  0.0132  ±0.74%   472973   fastest
   npm:js-base64 toUint8Array()                149,056.15  0.0060  0.6527  0.0068  0.0069  0.0107  0.0139  0.0229  ±0.38%   146233
   npm:uint8array-extras base64ToUint8Array()   25,034.52  0.0370  0.9187  0.0407  0.0399  0.0534  0.0612  0.1554  ±0.56%    24600   slowest

Node 24.21

 RUN  v5.0.4 /Users/sebastien/github/httpx/packages/encode

 ✓ |bench| bench/base64.bench.ts > Base64 implementations > encode (original size: 11.2 kB) 3789ms
   name                                           hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode node20 (Buffer).encode()  55,508.01  0.0164  0.1656  0.0182  0.0181  0.0274  0.0364  0.0722  ±0.16%    54841   fastest
   @httpx/encode purejs.encode()           36,819.97  0.0248  0.2531  0.0276  0.0280  0.0441  0.0552  0.1190  ±0.21%    36269
   @httpx/encode atob.encode()             24,294.31  0.0379  0.1952  0.0415  0.0420  0.0568  0.0837  0.1022  ±0.15%    24119   slowest
 ✓ |bench| bench/base64.bench.ts > Base64 implementations > decode (original size: 11.2 kB) 3789ms
   name                                           hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode node20 (Buffer).decode()  70,925.58  0.0114  0.6844  0.0146  0.0147  0.0263  0.0349  0.0756  ±0.28%    68562   fastest
   @httpx/encode atob.decode()             35,791.95  0.0226  0.1522  0.0282  0.0289  0.0370  0.0405  0.0767  ±0.13%    35436
   @httpx/encode purejs.decode()           27,049.82  0.0323  0.4097  0.0374  0.0382  0.0524  0.0629  0.1304  ±0.20%    26734   slowest
 ✓ |bench| bench/base64.bench.ts > Base64 implementations > fromUint8Array (original size: 15.2 kB) 4060ms
   name                                                    hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode node20 (Buffer).fromUint8Array()  952,656.27  0.0009  1.3467  0.0011  0.0011  0.0014  0.0015  0.0040  ±0.31%   926515   fastest
   @httpx/encode purejs.fromUint8Array()           104,940.94  0.0090  5.6985  0.0097  0.0095  0.0126  0.0143  0.0287  ±1.33%   102963
   @httpx/encode atob.fromUint8Array()              40,588.96  0.0223  0.2355  0.0249  0.0252  0.0329  0.0436  0.0970  ±0.17%    40171   slowest
 ✓ |bench| bench/base64.bench.ts > Base64 implementations > toUint8Array (original size: 15.2 kB) 3803ms
   name                                                  hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode node20 (Buffer).toUint8Array()  117,978.47  0.0079  4.0689  0.0098  0.0084  0.0439  0.0497  0.0792  ±2.40%   102431   fastest
   @httpx/encode atob.toUint8Array()              52,599.49  0.0177  0.9776  0.0192  0.0189  0.0248  0.0271  0.0445  ±0.23%    52192
   @httpx/encode purejs.toUint8Array()            33,410.52  0.0285  1.0480  0.0303  0.0303  0.0379  0.0413  0.0571  ±0.48%    33043   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > encode (original size: 11.2 kB) 3780ms
   name                                           hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode Base64.encode()           56,914.62  0.0163  0.1194  0.0177  0.0177  0.0229  0.0245  0.0409  ±0.10%    56620   fastest
   npm:js-base64 encode()                  24,513.63  0.0378  0.1944  0.0411  0.0412  0.0570  0.0835  0.0982  ±0.14%    24349
   npm:uint8array-extras stringToBase64()  13,468.30  0.0712  0.1812  0.0745  0.0743  0.1001  0.1112  0.1294  ±0.12%    13419   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > decode (original size: 11.2 kB) 3773ms
   name                                           hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode Base64.decode()           60,665.45  0.0144  0.1523  0.0166  0.0169  0.0220  0.0239  0.0409  ±0.11%    60243   fastest
   npm:js-base64 decode()                   8,700.54  0.1057  1.4065  0.1165  0.1181  0.1966  0.2323  0.2759  ±0.41%     8588
   npm:uint8array-extras base64ToString()   2,432.52  0.3783  1.1403  0.4165  0.4189  0.8120  0.8841  1.0080  ±0.61%     2402   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > fromUint8Array (original size: 15.2 kB) 4041ms
   name                                                hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode Base64.fromUint8Array()       950,730.97  0.0009  0.1338  0.0011  0.0011  0.0014  0.0015  0.0043  ±0.17%   924367   fastest
   npm:js-base64 fromUint8Array()               40,820.63  0.0222  0.7279  0.0249  0.0252  0.0347  0.0445  0.1158  ±0.25%    40223
   npm:uint8array-extras uint8ArrayToBase64()   17,543.22  0.0552  0.1793  0.0573  0.0575  0.0762  0.0847  0.1239  ±0.13%    17456   slowest
 ✓ |bench| bench/base64-compare.bench.ts > Base64 compared to js-base64 and uint8array-extras > toUint8Array (original size: 15.2 kB) 3781ms
   name                                               hz     min     max    mean     p75     p99    p995    p999     rme  samples
   @httpx/encode Base64.toUint8Array()         93,225.01  0.0079  4.0238  0.0120  0.0112  0.0460  0.0521  0.0879  ±1.85%    82992   fastest
   npm:js-base64 toUint8Array()                 8,611.64  0.1090  0.7092  0.1175  0.1177  0.1995  0.2300  0.3528  ±0.35%     8513
   npm:uint8array-extras base64ToUint8Array()   2,506.38  0.3699  1.0500  0.4028  0.4036  0.7218  0.7739  0.9109  ±0.51%     2483   slowest

See benchmark files for details.

Bundle size

Bundle size is tracked by a size-limit configuration

| Scenario (esm) | Size (brotli) | | --- | --: | | import { Base64 } from '@httpx/encode' (bun, deno) | ~ 390B | | import { Base64 } from '@httpx/encode' (node) | ~ 970B | | import { Base64 } from '@httpx/encode' (browser) | ~ 1.4kB | | import { Base64Uint8Array } from '@httpx/encode/base64/base64.uint8array' | ~ 390B | | import { Base64Atob } from '@httpx/encode/base64/base64.atob' | ~ 880B | | import { Base64Purejs } from '@httpx/encode/base64/base64.purejs' | ~ 1.1kB |

Compatibility

| Level | CI | Description | | --- | --- | --- | | Node | ✅ | CI for 22.x, 24.x & 26.x. | | Browser | ✅ | Tested with latest chrome (vitest/playwright) | | Browserslist | ✅ | defaults, > 0.28%, last 2 versions, Firefox ESR, not dead, not ios <= 15 | | Bun | ✅ | Tested with latest (at time of writing >= 1.3.3) | | Edge | ✅ | Ensured on CI with @vercel/edge-runtime. | | Cloudflare | ✅ | Ensured with @cloudflare/vitest-plugin (see wrangler.toml | | Typescript | ✅ | TS 5.7 + / are-the-type-wrong checks on CI. | | ES2022 | ✅ | Dist files checked with es-check | | Performance | ✅ | Monitored with codspeed.io |

For older browsers: most frontend frameworks can transpile the library (ie: nextjs...)

Contributors

Contributions are welcome. Have a look to the CONTRIBUTING document.

Sponsors

If my OSS work brightens your day, let's take it to new heights together! Sponsor, coffee, or star – any gesture of support fuels my passion to improve. Thanks for being awesome! 🙏❤️

Special thanks to

License

MIT © Sébastien Vanvelthem and contributors.