Open source2026 – Now
toklyn
Author and maintainer
An open-source TypeScript library for access and refresh token sessions: short-lived JWTs, refresh-token rotation with reuse detection, server-side sessions, and adapters for Express, Fastify, NestJS and Next.js.
- npm packages, released together
- 6
- production databases supported
- 5
- automated tests
- 375+
Key outcomes
- Rotates the refresh token on every use and revokes the whole session when a used token comes back, so a stolen token stops working for the attacker and the user alike
- Made rotation one atomic store operation, so two concurrent refreshes with the same token can never both succeed, with an optional grace window for clients that refresh in parallel
- Built one framework-neutral HTTP layer and thin adapters on top of it for Express, Fastify, NestJS and the Next.js App Router, in bearer or HttpOnly cookie mode
- Shipped production stores for PostgreSQL, MySQL/MariaDB, SQLite, MongoDB and Redis that work with the driver or ORM an app already uses, plus a contract test suite for custom stores
- Added JWKS publishing and remote verification, so other services can verify tokens with no shared secret and no session store
- Secure by default: hashed refresh tokens, pinned JWT algorithms, __Host- cookies, CSRF checks on cookie writes, and Web Crypto only, so the core also runs on the Edge Runtime
Case study
Why I built it
Every project I worked on re-implemented refresh tokens, and most got rotation and reuse detection wrong: tokens that never expire, refreshes that race each other, or a stolen token that keeps working after the user logs out. toklyn is the version I wanted to stop rewriting. You keep your own login logic (passwords, OAuth, magic links), and toklyn takes over from "this user is who they claim to be".
What it does
- Issues short-lived JWT access tokens and long-lived opaque refresh tokens, and stores sessions server-side
- Rotates the refresh token on every refresh and revokes the session when a consumed token is presented again, as RFC 9700 recommends
- Lets you list a user's sessions, revoke one, or sign a user out everywhere
- Runs an
onRefreshhook before each refresh, so a disabled user is signed out and role changes reach the next access token - Verifies tokens
offline(signature and expiry, no store call) oronline(the session must still be active, and it fails closed if the store is down)
How it works
Refresh tokens look like <sessionId>.<256-bit random>, and only a SHA-256 hash of the whole string is stored, so a database leak does not leak usable tokens. Each session has an absolute lifetime that rotation never extends.
Rotation is a single atomic store operation: validate, consume, insert the successor, or revoke on reuse. Each store implements it natively: one statement per operation on PostgreSQL, a locking transaction on MySQL, conditional updates on MongoDB and Lua scripts on Redis. A shared contract suite in toklyn/testing runs the same checks against every store, including custom ones.
Packages
- toklyn: the core, plus
toklyn/http(framework-neutral request handling),toklyn/testingandtoklyn/test-utils - @toklyn/express, @toklyn/fastify, @toklyn/nest and @toklyn/next: middleware, hooks, guards, decorators, route handlers and server-component helpers
- @toklyn/store: PostgreSQL, MySQL/MariaDB, SQLite, MongoDB and Redis/Valkey/Upstash stores
Security model
- Pins the JWT algorithm per key and requires
sub,sid,jti,iatandexp(RFC 8725) - Enforces minimum HMAC key sizes and fails at startup on a missing or weak secret
- Sets cookies
HttpOnly,Secureand__Host-, and treats duplicate cookies as missing to block cookie tossing - Checks Fetch Metadata and
Originon cookie-authenticated writes, and returns identical401responses withCache-Control: no-store - Publishes JWKS for asymmetric keys, with key caching, refetch on unknown
kidand an algorithm allow-list on the verifying side
Engineering and release
- One runtime dependency (
jose), Web Crypto only, ESM and CommonJS builds, and types checked withstrictand are-the-types-wrong - CI on Node 22 and 24 against real PostgreSQL, MySQL, MariaDB, MongoDB and Redis, plus Edge Runtime and Bun runs
- Property-based tests, CodeQL, OpenSSF Scorecard and an OpenSSF Best Practices passing badge
- Versioned and published with Changesets; runnable examples for every framework, database and ORM, including Prisma, Drizzle, TypeORM and Mongoose
