Fast Base64 encoding and decoding for Elm Bytes.
import Base64
Base64.fromBytes bytes -- Bytes -> String
Base64.toBytes "Zm9v" -- String -> Maybe Bytes
Base64.toBytesUnsafe "Zm9v" -- String -> Bytes (no validation)See the module docs for the full API.
elm install elm-cardano/base64Performance is a first-class concern for this package. Every function has been benchmarked and optimized, with multiple implementation strategies tested and compared. Here are the key techniques:
fromBytes reads 60 bytes per outer loop iteration (via Decode.map5 over five 12-byte Decode.map3 blocks), minimizing loop overhead. Each 12-byte block unpacks three Int32 words into four 24-bit groups and emits 16 base64 characters.(++) is O(1) in V8 (creates a rope node), which we exploit throughout. This beats List String accumulators with String.concat by ~11%.toBytes) validates input characters inline during the decode fold, using a bad accumulator that OR-collects sentinel values. One pass, no separate validation walk — within ~4% of the unsafe path.String.foldl-based decoding: The decoder operates on the input string directly via String.foldl, building output through Encode.Encoder lists, avoiding Bytes.Decode-side accumulation entirely.As a reference point, here is how we compare to danfishgold/base64-bytes (the most popular Elm Base64 package):
| Function | Size | elm-cardano/base64 | danfishgold/base64-bytes | Speedup |
|---|---|---|---|---|
fromBytes | 0-32 B | 18,144 ns | 20,599 ns | 14% |
fromBytes | 1024 B | 19,299 ns | 24,704 ns | 28% |
fromBytes | 10 kB | 190,233 ns | 242,915 ns | 28% |
toBytes | 16 B | 579 ns | 953 ns | 65% |
toBytes | 1024 B | 27,105 ns | 50,688 ns | 87% |
See bench/ for the full benchmarking setup and methodology.
See bench/REPORT.md for the history of attempted optimizations.
pnpm install
pnpm test # run tests
pnpm review # elm-review
pnpm format:check # check formatting
pnpm bench:build # build benchmarks
pnpm bench:test # run benchmark correctness checks