totp-generator

Generate TOTP one-time passcodes from a secret key using the native Web Crypto API, with a pure-JS fallback.

Library
npm
v2.0.1
314stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
61/100Good
Development Activity64
Maintenance52
Community48
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
68/100Good
Architecture78
Code Quality85
Innovation62
Learning Curve45

totp-generator is a small, dependency-light TypeScript library for generating Time-based One-Time Passwords (TOTP) per RFC 6238. Given a base32 (or ASCII) secret key, TOTP.generate() returns the current numeric OTP plus the millisecond timestamp it expires at, making it straightforward to build 2FA verification flows or drive automated end-to-end tests that must pass a login gate protected by an authenticator app.

The library defaults to SHA-1, 30-second periods, and 6-digit codes to match apps like Google Authenticator, but every parameter — algorithm (SHA-1/256/384/512), digit count, period, timestamp, and zero-padding — is configurable per call. Internally it prefers the runtime’s native Web Crypto API for HMAC signing and only falls back to the pure-JavaScript jssha implementation when Web Crypto is unavailable, keeping the common case fast while still working in constrained environments.

What You Get

  • An async TOTP.generate() method returning { otp, expires } from a base32 or ASCII secret key
  • Configurable digit count, hashing algorithm (SHA-1/256/384/512), time period, and explicit zero-padding
  • Native Web Crypto API usage for HMAC signing with automatic fallback to a pure-JS (jssha) implementation when Web Crypto is unavailable
  • Dual CJS/ESM builds with bundled TypeScript type declarations
  • Zero runtime configuration required — sensible RFC-6238-compatible defaults (SHA-1, 30s period, 6 digits) out of the box

Common Use Cases

  • Verifying a user-submitted TOTP code server-side during 2FA login
  • Programmatically generating valid TOTP codes in end-to-end tests that need to pass through a two-factor login screen
  • Building an admin or support tool that needs to compute a TOTP code from a stored secret
  • Implementing a self-hosted authenticator-style flow without depending on a paid auth provider’s TOTP APIs

Under The Hood

Architecture totp-generator is a single-class library: all logic lives in src/index.ts as static methods on the TOTP class, with generate() as the sole public entry point and a set of private static helpers (_sign, hex2dec, dec2hex, base32ToBuffer, asciiToBuffer, hex2buf, buf2hex) handling encoding conversions and HMAC signing. There is no external state, no class instantiation, and no dependency injection — the design is intentionally a flat, stateless utility, so the only thing that could break callers is a change to the generate() signature or its default option values.

Tech Stack The package is authored in TypeScript targeting ES2022, built with tsc plus terser for minification into separate CJS and ESM outputs (tsconfig-cjs.json / tsconfig-esm.json), and uses Bun as its dev/test runtime. Its only runtime dependency is jssha, used exclusively as a fallback HMAC implementation when the native Web Crypto API (globalThis.crypto or Node’s crypto.webcrypto) is unavailable. Biome handles linting and formatting in place of ESLint/Prettier.

Code Quality Tests live in src/index.spec.ts and run via Bun’s built-in test runner (bun test), covering standard RFC 6238/4226 test vectors, custom digit counts, all four supported hash algorithms, zero-padding edge cases, expiry-boundary timing, and both the native-crypto and jssha fallback code paths (the fallback test explicitly disables globalThis.crypto and Node’s webcrypto to force the fallback branch). Errors are handled explicitly — an invalid base32 character throws a descriptive Error rather than failing silently. TypeScript strict mode is enabled, and CI (GitHub Actions) runs Biome checks, the Bun test suite with coverage, and a compatibility matrix building and executing the compiled CJS/ESM output against Node 18, 20, 22, and 24.

What Makes It Unique Rather than committing to one HMAC implementation, the library actively prefers the platform’s native Web Crypto API and only reaches for a JS-based HMAC library as a fallback, caught via a try/catch around the native path — giving it lower overhead and no crypto polyfill weight in modern runtimes (browsers, Deno, Cloudflare Workers, current Node) while remaining functional in older or restricted environments. The surface area is deliberately minimal: one async method, sensible defaults matching mainstream authenticator apps, and full configurability of every RFC 6238 parameter when needed.

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