Skip to content
LogoLogo

@portable/base64

Functions

Base64.decode

Decodes base64 or base64url to bytes. Uses Uint8Array.fromBase64 where the runtime has it.

function decode(
  input: string | Uint8Array,
  options: decode.Options = {},
): Uint8Array<ArrayBuffer>;
OptionTypeDefaultDescription
alphabetAlphabet'base64'Alphabet of the input. 'mime' mode accepts both.
modeMode'loose'How to treat non-canonical input.

Throws

  • InvalidInputError When 'loose' or 'strict' mode finds a character or padding that is not allowed.
  • TruncatedError When 'loose' or 'strict' mode finds the input ending inside a group.
import * as Base64 from '@portable/base64';
 
new TextDecoder().decode(Base64.decode('aGVs\r\nbG8')); // 'hello'
Base64.decode('-_8', { alphabet: 'base64url' }); // Uint8Array [0xfb, 0xff]
Base64.decode('YQ==\r\nYg==', { mode: 'mime' }); // the bytes of 'ab'

Base64.encode

Encodes bytes, or a string as UTF-8, to base64. Uses Uint8Array.prototype.toBase64 where the runtime has it.

function encode(
  input: Uint8Array | string,
  options: encode.Options = {},
): string;
OptionTypeDefaultDescription
alphabetAlphabet'base64''base64' uses + and /, 'base64url' uses - and _ (RFC 4648 §5).
lineLengthnumber | falsefalseCharacters per line, or false for one line. MIME uses 76.
newlinestring'\r\n'Inserted between lines when lineLength is set.
omitPaddingbooleanfalseLeave out the trailing = characters.
import * as Base64 from '@portable/base64';
 
Base64.encode('hello'); // 'aGVsbG8='
Base64.encode(new Uint8Array([0xfb, 0xff]), {
  alphabet: 'base64url',
  omitPadding: true,
}); // '-_8'
Base64.encode(attachment, { lineLength: 76 }); // MIME body, lines joined with CRLF

Classes

Base64.DecoderStream

A TransformStream that decodes base64 text or bytes. The output is the same as decode of all the input at once, however the input is chunked, so line breaks, padding and groups of four characters can be split anywhere. Invalid input in 'loose' or 'strict' mode errors the stream with an InvalidInputError or TruncatedError.

class DecoderStream extends TransformStream<
  string | Uint8Array,
  Uint8Array<ArrayBuffer>
> {
  constructor(options: DecoderStream.Options = {});
}
OptionTypeDefaultDescription
alphabetimport("./encode.js").Alphabet'base64'Alphabet of the input. 'mime' mode accepts both.
modeimport("./decode.js").Mode'loose'How to treat non-canonical input.
signalAbortSignalErrors the stream with signal.reason when the signal aborts, which makes pipeThrough cancel the source.
import * as Base64 from '@portable/base64';
 
const bytes = mimePartBody.pipeThrough(
  new Base64.DecoderStream({ mode: 'mime' }),
);

Base64.EncoderStream

A TransformStream that encodes bytes, or strings as UTF-8, to base64 text as ASCII bytes. The output is the same as encode of all the input at once, however the input is chunked: lines break at the same places, and no output chunk ends with a line ending.

class EncoderStream extends TransformStream<
  Uint8Array | string,
  Uint8Array<ArrayBuffer>
> {
  constructor(options: EncoderStream.Options = {});
}
OptionTypeDefaultDescription
alphabetimport("./encode.js").Alphabet'base64''base64' uses + and /, 'base64url' uses - and _ (RFC 4648 §5).
lineLengthnumber | falsefalseCharacters per line, or false for one line. MIME uses 76.
newlinestring'\r\n'Inserted between lines when lineLength is set.
omitPaddingbooleanfalseLeave out the trailing = characters.
signalAbortSignalErrors the stream with signal.reason when the signal aborts, which makes pipeThrough cancel the source.
import * as Base64 from '@portable/base64';
 
const response = await fetch('https://example.com/logo.png');
const body = response.body!.pipeThrough(
  new Base64.EncoderStream({ lineLength: 76 }),
);

Errors

Base64.InvalidInputError

Thrown in 'loose' and 'strict' mode for a character outside the alphabet, misplaced padding, or, in 'strict' mode, non-zero bits before the padding.

class InvalidInputError extends Errors.InvalidInputError {
  readonly kind: string;
}
import * as Base64 from '@portable/base64';
 
try {
  Base64.decode('YW*j');
} catch (error) {
  if (error instanceof Base64.InvalidInputError) {
    console.log(error.message);
  }
}

Base64.TruncatedError

Thrown in 'loose' and 'strict' mode when the input ends inside a group of four characters that can't be completed: one leftover character, a single = where two are needed, or, in 'strict' mode, missing padding.

class TruncatedError extends Errors.TruncatedError {
  readonly kind: string;
}
import * as Base64 from '@portable/base64';
 
try {
  Base64.decode('YWJjZ');
} catch (error) {
  if (error instanceof Base64.TruncatedError) {
    console.log('incomplete base64');
  }
}

Types

Base64.Mode

How decode treats input that is not canonical base64.

  • 'loose': Uint8Array.fromBase64 with lastChunkHandling: 'loose'. ASCII whitespace is skipped, padding is optional, and any other character outside the alphabet throws.
  • 'strict': as 'loose', but padding is required and the unused bits before it must be zero.
  • 'mime': RFC 2045 §6.8. Every character outside the alphabet is skipped, both alphabets are accepted, each = ends a segment that is decoded on its own, and nothing throws.
type Mode =  |  | ;

Base64.Alphabet

The standard alphabet with + and /, or the URL-safe one with - and _ (RFC 4648).

type Alphabet =  | ;