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,289stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
77/100Good
Development Activity84
Maintenance72
Community52
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
92/100Excellent
Architecture90
Code Quality92
Innovation90
Learning Curve95

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
92%
GPL 3.0

Blinko

Knowledge Management · Note Taking

10,992

A self-hosted, AI-powered card note-taking tool that lets you capture fleeting thoughts instantly and retrieve them with natural language search.

View details
80
Repo Health
69
Technical
63
Dependency
Built with
TypeScript92%
Updated 1 weeks ago
TypeScript
96%
Other

Cal.diy

Scheduling

48,218

The 100% MIT-licensed, community-driven scheduling platform — self-host your own booking infrastructure with no enterprise strings attached.

View details
95
Repo Health
86
Technical
65
Dependency
Built with
TypeScript96%
Updated yesterday
JavaScript
83%
Other

Countly

Analytics · Marketing

5,896

Privacy-first, self-hosted analytics and customer engagement platform with full data ownership, GDPR compliance, and AI-powered insights across mobile, web, desktop, and IoT.

View details
95
Repo Health
82
Technical
65
Dependency
Built with
JavaScript83%
Updated 3 days ago
TypeScript
81%
Other

Directus

CMS · Low Code Platforms

37,783

Connect any SQL database and get instant REST and GraphQL APIs, a visual management Studio, and a native MCP server for AI agents — free for most organizations.

View details
92
Repo Health
82
Technical
76
Dependency
Built with
TypeScript81%
Vue18%
Updated 3 days ago
TypeScript
97%
Other

Formbricks

Forms Surveys · Marketing · Analytics

12,897

Open-source experience management platform for in-app, website, email, and link surveys — privacy-first and fully self-hostable.

View details
93
Repo Health
81
Technical
70
Dependency
Built with
TypeScript97%
Updated yesterday
JavaScript
47%
MIT

Ghost

CMS · Blogging

55,191

Open source headless Node.js CMS for professional publishing, paid memberships, and newsletters with a fully owned audience.

View details
96
Repo Health
85
Technical
67
Dependency
Built with
JavaScript47%
TypeScript47%
Updated yesterday
TypeScript
83%
Apache 2.0

Grist

Databases · No Code Platforms

11,726

A modern relational spreadsheet that combines Python-powered formulas, drag-and-drop dashboards, and granular access controls in a self-hostable, SQLite-backed data platform.

View details
91
Repo Health
93
Technical
66
Dependency
Built with
TypeScript83%
Python11%
Updated yesterday
Rust
52%
Other

hoodik

File Storage · Security

1,468

Self-hosted, end-to-end encrypted cloud storage with browser-based encryption and S3-compatible storage support

View details
75
Repo Health
71
Technical
64
Dependency
Built with
Rust52%
TypeScript33%
Vue14%
Updated 1 weeks ago
TypeScript
61%
EPL-2.0

Huly Platform

Project Management · Team Chat · Collaboration

27,586

Open-source all-in-one workspace that replaces Linear, Jira, Slack, and Notion for product and engineering teams.

View details
89
Repo Health
86
Technical
62
Dependency
Built with
TypeScript61%
Svelte34%
Updated 1 weeks 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

Search