This is a pure TypeScript Base64-URL encoder/decoder for JavaScript strings with UTF-8 support.
If you've found it, you're already aware that:
- btoa and atob only work on ASCII strings, and they're not always available in cool new JS runtimes
- Buffer is only in Node.js
- TextEncoder only works in browsers
This implementation allows you to encode any JavaScript string (emojis and multi-byte characters allowed!) to and from UTF-8 and then encode it as Base64-URL. It's great for:
- Working with JWTs on any JS runtime
- Encoding JavaScript strings to UTF-8 when serializing or parsing binary formats
It's a no-dependencies / no-depends library. Just copy the src/base64url.ts
file in your project. It's mostly finished software, so it's unlikely you'll
need to update it.
To encode to Base64-URL:
import { stringToBase64URL } from "./base64url";
stringToBase64URL("This will be encoded to UTF-8 then Base64-URL");
To decode from Base64-URL:
import { stringFromBase64URL } from "./base64url";
stringFromBase64URL(
"VGhpcyB3aWxsIGJlIGVuY29kZWQgdG8gVVRGLTggdGhlbiBCYXNlNjQtVVJM",
);
To encode a string to UTF-8:
import { stringToUTF8 } from "./base64url";
stringToUTF8("This will be encoded as UTF-8", (byte: number) => {
// write this byte to a stream or buffer
});
To decode UTF-8 bytes to a string:
import { stringFromUTF8 } from "./base64url";
const result: string[] = [];
const state = { utf8seq: 0, codepoint: 0 };
const onCodepoint = (codepoint: number) => {
result.push(String.fromCodePoint(codepoint));
};
for (let byte of buffer) {
// buffer holds all the UTF-8 bytes,
// call this function for each byte
stringFromUTF8(byte, state, onCodepoint);
}
const string = result.join("");
To convert a Uint8Array to Base64-URL:
import { byteToBase64URL } from "./base64url";
let bytes: Uint8Array;
const result: string[] = [];
const state = { queue: 0, queuedBits: 0 };
const onChar = (char: string) => {
result.push(char);
};
bytes.map((byte) => byteToBase64URL(byte, state, onChar));
// always call with `null` after processing all bytes
byteToBase64URL(null, state, onChar);
const string = result.join("");
To convert Base64-URL to a Uint8Array:
import { byteFromBase64URL } from "./base64url";
const result: number[] = [];
const state = { queue: 0, queuedBits: 0 };
const onByte = (byte: number) => {
result.push(byte);
};
for (let i = 0; i < string.length; i += 1) {
byteFromBase64URL(string.charCodeAt(i), state, onByte);
}
const bytes = new Uint8Array(result);