StableLib (@stablelib/base64)

Constant-time Base64 encoding and decoding for TypeScript and JavaScript, including a URL-safe variant.

Library
npm
v2.0.1
221stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
43/100Fair
Development Activity8
Maintenance20
Community64
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
73/100Good
Architecture78
Code Quality80
Innovation68
Learning Curve65

@stablelib/base64 is a small, dependency-free TypeScript library that implements Base64 encoding and decoding, including both the standard alphabet and the URL-safe variant used in JWTs, WebAuthn credentials, and other web-safe encodings. It is part of the StableLib monorepo, a collection of focused cryptography and encoding primitives maintained with an emphasis on correctness and clear code over premature optimization.

The encoder and decoder run in constant time, avoiding branch-based lookups that could leak information about the encoded data through timing side channels — a property that matters when Base64 is used to serialize secrets such as keys, tokens, or ciphertexts rather than only public data. The package exposes both class-based Coder/URLSafeCoder objects for custom padding behavior and simple encode/decode functions for the common case, and ships as an ES module with bundled TypeScript type definitions.

What You Get

  • Standard Base64 codec - encode/decode functions implementing RFC 4648 standard Base64 with = padding.
  • URL-safe variant - encodeURLSafe/decodeURLSafe swap +// for -/_, matching the alphabet used by JWTs and WebAuthn.
  • Constant-time implementation - encoding and decoding avoid data-dependent branches, reducing timing side-channel risk when encoding secret material.
  • Configurable padding - the underlying Coder/URLSafeCoder classes accept a custom padding character, including an empty string to omit padding.
  • Length helpers - encodedLength, maxDecodedLength, and decodedLength let callers pre-size buffers without performing a full encode/decode pass.

Common Use Cases

  • Encoding binary cryptographic output (keys, signatures, hashes) from other StableLib packages as transportable strings.
  • Implementing WebAuthn or JOSE/JWT libraries that require URL-safe Base64 without padding.
  • Serializing Uint8Array payloads for JSON APIs, config files, or QR codes.
  • Building custom binary/text codecs that need predictable, side-channel-resistant Base64 as a building block.

Under The Hood

Architecture The package is a single-file module (base64.ts) inside the StableLib monorepo’s independent packages/base64 workspace. It defines one base Coder class holding the encode/decode logic and a configurable padding character, and a URLSafeCoder subclass that overrides only the two byte-mapping methods (_encodeByte/_decodeChar) to swap in the URL-safe alphabet — a small, clean instance of inheritance for alphabet variation rather than duplicating the surrounding length/padding logic. Two module-level singleton instances (stdCoder, urlSafeCoder) back the plain encode/decode/encodeURLSafe/decodeURLSafe function exports, so the functional API is a thin, stateless wrapper over the class API; any change to the base Coder’s core loop would ripple through both the class-based and function-based surfaces at once.

Tech Stack Written in TypeScript (^5.5.2), compiled per-package with tsc against a shared base tsconfig in the repo’s configs/ directory. The monorepo is orchestrated with Lerna (^8.1.5, independent per-package versioning) driving lerna bootstrap/lerna run for build/test/bench across all packages/*. Tests run on Vitest (^1.6.0); linting uses ESLint 8 with typescript-eslint (^7.14.1) recommended rules; API docs are generated with TypeDoc. CI (GitHub Actions, build-and-test.yml) runs npm ci, npm run build, and npm test on Node 20 for every push and PR. The published package itself declares zero runtime dependencies — its only devDependency is StableLib’s own @stablelib/benchmark, used solely by the bench script.

Code Quality Tests (base64.test.ts, Vitest) cover the RFC 4648 test vectors plus edge cases (empty input, one/two/three trailing bytes, an all-zeros run) for both the standard and URL-safe alphabets, and assert that a set of malformed inputs (bad padding, wrong length, non-alphabet characters) throw rather than silently decode garbage. Error handling is explicit: decode throws descriptive Errors for incorrect padding and out-of-alphabet characters instead of failing silently. Naming is consistent (PascalCase classes, camelCase functions, underscore-prefixed internal methods), typing is complete with no use of any, and the shared ESLint config enforces consistent-type-imports. No test-coverage reporting is configured, but the test suite is present and exercises both success and failure paths directly.

API Design The public surface is intentionally small: most consumers need only encode/decode (and their URL-safe counterparts), requiring zero setup or class instantiation. The Coder/URLSafeCoder classes are available underneath for callers who need a non-default padding character, keeping the common case boilerplate-free while still exposing configurability. Dedicated encodedLength/decodedLength/maxDecodedLength helpers let callers size buffers ahead of time, a small but genuinely useful ergonomic detail many Base64 libraries omit. The constant-time character mapping is a real, if narrow, differentiator versus typical Base64 implementations, which usually use plain lookup tables and don’t consider timing side channels at all.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search