npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

quantum-safe-ts

v1.0.0

Published

Hybrid post-quantum cryptography for TypeScript and JavaScript: ML-KEM, ML-DSA, SLH-DSA, hybrid envelopes and signatures. Rust core compiled to WASM, wire-compatible with quantum-safe-py.

Readme

quantum-safe-ts

Hybrid post-quantum cryptography for TypeScript and JavaScript: ML-KEM, ML-DSA, SLH-DSA, hybrid X25519 / Ed25519 / P-256 + post-quantum encryption and signatures, post-quantum JWTs, and a CNSA 2.0 profile. A memory-safe Rust core compiled to WebAssembly, behind a fully typed API, byte-compatible with quantum-safe-py.

npm install quantum-safe-ts

Quick start

The shortest path: strings and bytes in, strings and bytes out, nothing to free.

import { easy } from 'quantum-safe-ts';

const { publicKey, secretKey } = easy.generateEncryptionKeys();     // PEM strings, X25519 + ML-KEM-768
const sealed = easy.encrypt(publicKey, 'attack at dawn');           // Uint8Array
const plain = easy.decrypt(secretKey, sealed);                      // Uint8Array
if (new TextDecoder().decode(plain) !== 'attack at dawn') throw new Error('round trip failed');

const signer = easy.generateSigningKeys();                           // Ed25519 + ML-DSA-65
const signed = easy.sign(signer.secretKey, 'pay 10', { context: 'payments' });
const message = easy.verify(signer.publicKey, signed, { context: 'payments' }); // throws unless valid
if (new TextDecoder().decode(message) !== 'pay 10') throw new Error('verify failed');

On Node.js this works immediately. In browsers, Deno, Bun and edge runtimes call await init() once first (see below).

When you need to keep secret keys inside WebAssembly memory and wipe them on demand, use the class API. (using needs TypeScript 5.2+ with lib including ESNext.Disposable, and runs natively on Node 24+; elsewhere transpile it or write try { ... } finally { pair.free(); }.)

import { init, HybridKEM, Envelope, utf8 } from 'quantum-safe-ts';

await init(); // required outside Node.js; a no-op on Node.js

const kem = new HybridKEM();          // X25519 + ML-KEM-768
using pair = kem.generateKeyPair();   // `using` wipes the secret key from WASM memory on scope exit

const sealed = Envelope.seal(utf8('attack at dawn'), pair.publicKey, { aad: utf8('msg-1') });
const plain = Envelope.open(sealed, pair.secretKey); // Uint8Array
if (plain.length !== 14) throw new Error('unexpected length');

What it provides

| Capability | API | Algorithms | |---|---|---| | One-call encryption and signing | easy | defaults: X25519+ML-KEM-768, Ed25519+ML-DSA-65 | | Key encapsulation | HybridKEM, KEM | X25519+ML-KEM-512/768/1024, P-256+ML-KEM-512/768, P-384+ML-KEM-1024, X-Wing, pure ML-KEM-512/768/1024 | | Public-key encryption (anonymous: no sender authentication) | Envelope, SealedMessage | any hybrid KEM + AES-256-GCM | | Signatures | Sign, HybridSign, SignedMessage | ML-DSA-44/65/87, Ed25519+ML-DSA-*, P-256+ML-DSA-44/65, P-384+ML-DSA-87, SLH-DSA (12 parameter sets); plus the -v2 format of each ML-DSA suite (native FIPS 204 context over a wrapped message, not a standard signature over your message; quantum-safe-py 0.3.2+ reads it too) | | Stateful hash-based signatures | Lms (verify, everywhere), LmsSigner (sign, Node.js, durable state) | LMS / HSS (RFC 8554, SHA-256) | | JWT | JWTSigner/JWTVerifier, StandardJwt | quantum-safe-py-compatible, and RFC 9964 (ML-DSA for JOSE) | | Password KDF | deriveMasterKey | Argon2id | | Keys | PublicKey, SecretKey, KeyPair | CBOR, PEM, JWK (public), fingerprints, migration state | | Migration | Upgrader, MigrationStateManager | classical to hybrid key upgrade, state machine with validated transitions and an audit trail, py store converters | | Compliance report | cnsa2.report(), cnsa2.enforce() | CNSA 2.0 parameter check, with limits stated |

Defaults match quantum-safe-py (NIST category 3). CNSA 2.0 requires ML-KEM-1024 and ML-DSA-87: use cnsa2.kem() and ML-DSA-87 (and cnsa2.hybridSign() reports partial), or run cnsa2.report() to see where a configuration falls short.

Where it runs

Every row is exercised by a test that installs the packed npm tarball into a fresh project.

| Environment | Notes | |---|---| | Node.js 20 (end of life), 22, 24 (ESM and CommonJS) | Initialises on import. | | Chromium, Firefox, WebKit | await init(). No bundler configuration (the WASM is embedded). | | Vite 7, webpack 5, esbuild, Next.js 16, SvelteKit 2 | Default configuration, no WASM plugin. | | Cloudflare Workers | await init({ wasm }) with the precompiled module (Workers forbid compiling WASM from bytes). | | Deno 2, Bun | From node_modules. | | Chrome extensions (Manifest V3) | Needs 'wasm-unsafe-eval' in the extension CSP. |

Not supported: React Native. About 455 KiB of gzipped WebAssembly (compiled for speed), embedded as base64 in the default entry (about 680 KiB gzipped of JavaScript; import quantum-safe-ts/slim and pass the .wasm to init to avoid that; tree-shaking cannot drop algorithms).

Compatible with quantum-safe-py, and what that means

Envelopes, keys (CBOR / PEM / JWK), signed messages, signatures, JWTs and migration records are byte-compatible in both directions and verified in CI against the real Python library. That is compatibility, not general interoperability: quantum-safe-py's hybrid combiner and signature context are its own constructions. They are not X-Wing, not TLS X25519MLKEM768, and not FIPS 204's native context. For data other ecosystems must read, use HybridKEM('X-Wing') and StandardJwt.

Errors, memory and secrets

Every failure is a QuantumSafeError subclass with a stable code (for example QS_DECRYPTION_FAILED) and a hint. Match with instanceof or code, never by parsing message. Secret keys live in WASM memory; the owned secret buffers are zeroized on .free() (copies made while passing arguments or parsing may remain in WebAssembly memory; see SECURITY.md) by .free() or a using scope. Copies you extract (exportBytes(), toPem(), plaintext, and every key string the easy layer hands you) live in the JavaScript heap, where this library cannot wipe them.

For AI coding agents

llms.txt and llms-full.txt ship in this package, and every code example in llms-full.txt is executed in CI. Also available: quantum-safe-mcp (a read-only MCP server) and quantum-safe-audit (finds classical crypto in your code).

License

Apache-2.0.