Module encoding/base64

encoding/base64
Stability: unstable — the alphabet and the padding rule are baked into the function NAMES, and that is the open question. `base64_encode` uses the standard alphabet WITH padding, `base64_encode_url` the URL-safe alphabet WITHOUT it, and there is no way to ask for the other two combinations; both decoders accept padded and unpadded input alike, so `base64_decode` is Rust's `STANDARD` and `STANDARD_NO_PAD` engines at once. Rust's `base64` crate separates the alphabet from the padding policy into a configurable `Engine` precisely because four names do not scale, and a third axis (`Engine`'s `decode_padding_mode`) would make it eight here. Deciding whether Yo grows an options value or keeps naming the combinations is what has to happen before this freezes. Two smaller things ride along. The decode leniency is wider than Rust's: ALL trailing `=` are stripped before the length check, so `"QUJD===="` is accepted where Rust rejects excess padding — a canonical-form check would turn input that decodes today into an error. And the errors come from the shared `EncodingError` in `std/encoding/error.yo`, which gained its `pos` fields on 2026-09-09 and has not been through a release; whether one enum serves three codecs or splits per codec is that module's own open question. The names also still stutter (D2): `base64_encode` repeats the module it lives in, and the decided direction is `base64.encode` on the imported module value — listed as STILL OPEN in `plans/STD_API_STABILIZATION.md` §4 for the whole encoding group. — stable modules only change additively; this one may still change.

Base64 encoding and decoding (RFC 4648) with standard and URL-safe variants.

Example

base64 :: import("std/encoding/base64");

s := base64.encode(data);
b := base64.decode(s.to_string()).unwrap();

Stability

unstable — the alphabet and the padding rule are baked into the function NAMES, and that is the open question. base64_encode uses the standard alphabet WITH padding, base64_encode_url the URL-safe alphabet WITHOUT it, and there is no way to ask for the other two combinations; both decoders accept padded and unpadded input alike, so base64_decode is Rust's STANDARD and STANDARD_NO_PAD engines at once. Rust's base64 crate separates the alphabet from the padding policy into a configurable Engine precisely because four names do not scale, and a third axis (Engine's decode_padding_mode) would make it eight here. Deciding whether Yo grows an options value or keeps naming the combinations is what has to happen before this freezes.

Two smaller things ride along. The decode leniency is wider than Rust's: ALL trailing = are stripped before the length check, so "QUJD====" is accepted where Rust rejects excess padding — a canonical-form check would turn input that decodes today into an error. And the errors come from the shared EncodingError in std/encoding/error.yo, which gained its pos fields on 2026-09-09 and has not been through a release; whether one enum serves three codecs or splits per codec is that module's own open question.

The names also still stutter (D2): base64_encode repeats the module it lives in, and the decided direction is base64.encode on the imported module value — listed as STILL OPEN in plans/STD_API_STABILIZATION.md §4 for the whole encoding group.

Functions

encode function
fn(data : ArrayList(u8)) -> String

Encode bytes as standard base64 with padding.

Parameters

NameTypeNotes
dataArrayList(u8)

Returns: String

encode_url function
fn(data : ArrayList(u8)) -> String

Encode bytes as URL-safe base64 without padding.

Parameters

NameTypeNotes
dataArrayList(u8)

Returns: String

decode function
fn(s : String) -> Result(ArrayList(u8), EncodingError)

Decode a standard base64 string to bytes (D13 — a pure transform returns a Result). .Err on a symbol outside the alphabet (InvalidChar), a length of 1 mod 4 (InvalidLength), or a final symbol with non-zero unused bits (InvalidLastSymbol). Padding is optional and, when present, trailing.

Parameters

NameTypeNotes
sString

Returns: Result(ArrayList(u8), EncodingError)

decode_url function
fn(s : String) -> Result(ArrayList(u8), EncodingError)

Decode a URL-safe base64 string to bytes.

Parameters

NameTypeNotes
sString

Returns: Result(ArrayList(u8), EncodingError)

decode_exn function
fn(s : String, exn : Exception) -> ArrayList(u8)

decode as an effect: throws the EncodingError through exn instead of returning it. Kept for callers already inside an effect scope.

Parameters

NameTypeNotes
sString
exnException

Returns: ArrayList(u8)

decode_url_exn function
fn(s : String, exn : Exception) -> ArrayList(u8)

decode_url as an effect.

Parameters

NameTypeNotes
sString
exnException

Returns: ArrayList(u8)

base64_encode function
fn(data : ArrayList(u8)) -> String

DEPRECATED, removed in v0.2.32: call base64.encode.

Parameters

NameTypeNotes
dataArrayList(u8)

Returns: String

fn(data : ArrayList(u8)) -> String

DEPRECATED, removed in v0.2.32: call base64.encode_url.

Parameters

NameTypeNotes
dataArrayList(u8)

Returns: String

base64_decode function
fn(s : String) -> Result(ArrayList(u8), EncodingError)

DEPRECATED, removed in v0.2.32: call base64.decode.

Parameters

NameTypeNotes
sString

Returns: Result(ArrayList(u8), EncodingError)

fn(s : String) -> Result(ArrayList(u8), EncodingError)

DEPRECATED, removed in v0.2.32: call base64.decode_url.

Parameters

NameTypeNotes
sString

Returns: Result(ArrayList(u8), EncodingError)

fn(s : String, exn : Exception) -> ArrayList(u8)

DEPRECATED, removed in v0.2.32: call base64.decode_exn.

Parameters

NameTypeNotes
sString
exnException

Returns: ArrayList(u8)

fn(s : String, exn : Exception) -> ArrayList(u8)

DEPRECATED, removed in v0.2.32: call base64.decode_url_exn.

Parameters

NameTypeNotes
sString
exnException

Returns: ArrayList(u8)