// the find
panva/jose
JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes
jose is a full JOSE spec implementation in TypeScript with zero dependencies, built on the Web Crypto API so it runs identically in Node.js, browsers, Cloudflare Workers, Deno, and Bun. It covers the whole stack: JWT signing/verification, JWE encryption, JWK import/export, and JWKS (both local and remote with caching). If you're doing auth token work in JavaScript and don't want to pull in jsonwebtoken plus three other packages, this is the one.
- Zero dependencies and pure Web Crypto API underneath — no native bindings, no OpenSSL version surprises, and the same code path runs everywhere. That's genuinely hard to pull off at this scope.
- Covers the full JOSE surface area including JWE (encrypted JWTs), all three serialization forms (Compact, Flattened JSON, General JSON), and modern algorithms like ML-DSA and ECDH-ES. Most auth libraries stop at HS256/RS256.
- Remote JWKS handling is built-in with caching and a timeout error class — the detail work (key rotation, concurrent fetch deduplication) that you'd have to wire up yourself with any lower-level library.
- Algorithm implementations are tested against RFC7520 test vectors and the library tracks new specs (RFC9864 fully-specified algorithms, RFC9964 ML-DSA) close to publication. Not just JWT-circa-2015.
- CJS support requires Node.js 20.19+ or 22.12+ via require(esm) — older Node.js projects still need a wrapper or a bundler step, and the README buries this in a footnote.
- Algorithm availability varies by runtime and is documented only in GitHub issue threads rather than a single reference table. You'll be clicking through six separate issues to check if your target runtime supports ECDH-ES+A256KW.
- No built-in support for PKCS#12 / PFX bundles, so if you're importing certificates from enterprise systems, you're on your own for the extraction step before jose can touch the key.
- The test suite requires running separate scripts per runtime rather than a single command — cross-runtime CI is genuinely complex but it means local verification of 'does this work in Bun?' isn't obvious from the repo root.