otplib

TypeScript-first TOTP and HOTP library with a pluggable crypto/base32 architecture for Node, Bun, Deno, and browsers.

Library
npm
v13.5.0
2,298 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
83 /100 Excellent
Development Activity 96
Maintenance 84
Community 52
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
92 /100 Excellent
Architecture 90
Code Quality 92
Innovation 90
Learning Curve 95

otplib is a TypeScript-first library for generating and verifying one-time passwords, covering both RFC 6238 (TOTP) time-based codes and RFC 4226 (HOTP) counter-based codes, and staying compatible with Google Authenticator, Authy, 1Password, and other authenticator apps. Version 13 is a ground-up rewrite around a plugin interface: cryptographic HMAC operations and Base32 encoding/decoding are each swapped in through a CryptoPlugin or Base32Plugin, with security-audited defaults (@noble/hashes, @scure/base) shipped out of the box so most consumers never touch the plugin layer directly.

The library is published as a monorepo of scoped packages — @otplib/core (shared types, crypto/base32 context wrappers, error hierarchy), @otplib/hotp and @otplib/totp (the RFC algorithms), @otplib/uri (otpauth:// URI generation for QR codes), several @otplib/plugin-* packages for alternate crypto/encoding backends, and migration adapters for older otplib majors — with the otplib package itself acting as a thin, zero-config facade that re-exports a functional API (generate, verify, generateSecret, generateURI) and an equivalent OTP class API. Both async and sync variants are available depending on whether the selected crypto plugin supports synchronous operations.

Security guardrails are a deliberate design feature rather than an afterthought: secrets shorter than RFC 4226’s recommended 16 bytes throw a SecretTooShortError unless a caller explicitly overrides MIN_SECRET_BYTES via createGuardrails(), and token comparison uses constant-time equality to avoid timing side-channels. The project ships a documented tradeoff (loosening the guardrail to interoperate with the shorter secrets found in many RFC test vectors and tutorials) instead of silently accepting insecure input.

What You Get

  • Functional API (generate, verify, generateSecret, generateURI) and an equivalent OTP class API covering both usage styles
  • Both TOTP (time-based) and HOTP (counter-based) strategies from a single package, selected via a strategy option
  • A plugin interface for crypto (@otplib/plugin-crypto-noble, -node, -web) and Base32 encoding (@otplib/plugin-base32-scure, -alt), with audited defaults preselected
  • generateURI for building otpauth:// URIs consumable by QR-code generators for authenticator app enrollment
  • Sync and async variants of generate/verify (sync requires a sync-capable crypto plugin)
  • Configurable guardrails (createGuardrails) for secret length, period, and counter/window tolerances, with the defaults matching RFC recommendations
  • v11 and v12 compatibility adapter packages for migrating older otplib installations to v13’s rewritten API
  • A dedicated otplib-cli package for managing encrypted OTP vaults from the command line

Common Use Cases

  • Adding TOTP-based two-factor authentication (2FA) login to a web or mobile backend, generating QR-enrollment URIs and verifying user-submitted codes
  • Building an authenticator-app-compatible secret provisioning flow (Base32 secret + otpauth:// URI) for a new account security feature
  • Implementing HOTP for hardware tokens or counter-based one-time codes where a shared counter (not wall-clock time) drives the token
  • Replacing the default Node-only crypto backend with a Web Crypto or pure-JS (noble) plugin to run the same OTP logic in a browser, Deno, or edge runtime
  • Migrating an existing project off an older otplib major version using the provided v11/v12 adapter packages without rewriting call sites

Under The Hood

Architecture

The project is a Turborepo/pnpm monorepo where otplib is a thin facade composing independently versioned scoped packages: @otplib/core defines the CryptoPlugin/Base32Plugin interfaces plus CryptoContext/Base32Context wrapper classes that normalize algorithm names and delegate to whichever plugin is configured (packages/core/src/crypto-context.ts), @otplib/hotp and @otplib/totp implement the RFC algorithms against those contexts, @otplib/uri builds otpauth:// URIs, and a family of @otplib/plugin-crypto-*/@otplib/plugin-base32-* packages supply swappable backends (Noble/pure-JS, Node crypto, Web Crypto, scure Base32, alternate encodings). The otplib package’s functional.ts and class.ts both sit on top of the same generate/verify primitives, dispatching by strategy (totp/hotp) through an executeByStrategy helper, so the two public API surfaces stay behaviorally identical by construction rather than by convention.

Tech Stack

TypeScript throughout, built per-package with tsup into ESM, CJS, and a browser-ready IIFE global bundle; Turborepo orchestrates builds/lint/typecheck across the workspace and pnpm manages the monorepo’s internal workspace:* dependencies. Testing runs on Vitest with coverage, property-based testing via fast-check, and Stryker for mutation-testing the test suite itself; VitePress (with typedoc-generated API reference) powers the docs site, and lefthook wires pre-commit checks. Default runtime dependencies are @noble/hashes and @scure/base, both independently audited cryptography libraries.

Code Quality

The repo carries 44 test files, a typed error hierarchy rooted in OTPError (with SecretError, HMACError, AlgorithmError, AlgorithmUnsupportedError, ConfigurationError subclasses using ES2022 cause chaining), and constant-time token comparison to avoid timing side-channels during verification. Guardrail validation (secret length, period, counter/window bounds) is centralized and overridable rather than hardcoded, and the CI pipeline separately runs lint, typecheck, unit tests, and distribution tests against Node, Bun, and Deno consumption of the published package, plus a Docker-based smoke test.

API Design The package favors zero-configuration defaults (generate({ secret }) works with no plugin wiring) while still exposing the full plugin surface for callers who need a different crypto or encoding backend, and it offers both a functional and class-based API rather than forcing one style. Guardrail overrides and hooks are opt-in escape hatches documented alongside their security tradeoffs (e.g. the MIN_SECRET_BYTES override needed to interoperate with common shorter RFC test-vector secrets), and separate v11/v12 adapter packages absorb the breaking-change migration cost of the v13 rewrite instead of leaving existing consumers stranded.

Used by 22 apps in this directory

TypeScript
96%
Other

Infisical

Devops · Security

29,961

The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.

View details
91
Repo Health
84
Technical
64
Dependency
Built with
TypeScript 96%
Updated 5 days ago
TypeScript
77%
Other

Joplin

Note Taking

56,853

The privacy-first, open-source note-taking app with end-to-end encrypted sync, AI assistance, and a powerful plugin ecosystem across every platform.

View details
93
Repo Health
87
Technical
60
Dependency
Built with
TypeScript 77%
JavaScript 14%
Updated 6 days ago
TypeScript
98%
MPL 2.0

Logto

Authentication

14,769

Open-source auth infrastructure for SaaS and AI apps with OIDC, SAML, and RBAC

View details
92
Repo Health
83
Technical
63
Dependency
Built with
TypeScript 98%
Updated 6 days ago
TypeScript
88%
Apache 2.0

Medplum

Authentication · Databases · Developer Tools

2,760

An open-source, FHIR-native healthcare platform that gives developers a compliant backend, authentication, a React component library, and serverless bots to build clinical applications in weeks instead of years.

View details
93
Repo Health
90
Technical
71
Dependency
Built with
TypeScript 88%
Updated 5 days ago
TypeScript
92%
Other

n8n

Automation · No Code Platforms

208,437

Code when you need it, UI when you don't — the workflow automation platform built for technical teams who refuse to choose.

View details
95
Repo Health
87
Technical
62
Dependency
Built with
TypeScript 92%
Updated 6 days ago
TypeScript
49%
MIT

Nginx Proxy Manager

Developer Tools · Networking · Security

34,517

Manage Nginx reverse proxies and free Let's Encrypt SSL through a beautiful web interface — no Nginx expertise required.

View details
92
Repo Health
77
Technical
72
Dependency
Built with
TypeScript 49%
JavaScript 47%
Updated 1 weeks ago
TypeScript
85%
GPL 3.0

Notesnook

File Storage · Note Taking · Security

14,822

End-to-end encrypted, open-source note-taking where your data stays yours — even from the server.

View details
91
Repo Health
84
Technical
60
Dependency
Built with
TypeScript 85%
JavaScript 12%
Updated 5 days ago
JavaScript
64%
AGPL 3.0

overleaf

Collaboration · Productivity

18,266

Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.

View details
84
Repo Health
80
Technical
59
Dependency
Built with
JavaScript 64%
TypeScript 30%
Updated 1 months ago
TypeScript
100%
AGPL 3.0

RSSHub

Automation · Social Media

46,631

Turn any website into an RSS feed — social media, streaming platforms, and niche sites all become subscribable in seconds.

View details
94
Repo Health
82
Technical
71
Dependency
Built with
TypeScript 100%
Updated 5 days ago

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