The Node.js crypto module is the cryptography toolkit that ships with every Node.js installation. It backs the TLS layer in tls and https, the JWT libraries that power authentication for half the web, the bcrypt-and-friends password hashers, the AES file encryption snippets in countless server projects. Underneath, the module is mostly a thin wrapper around OpenSSL. Node.js bundles a specific OpenSSL version with each release line, and the algorithms Node exposes are largely the algorithms OpenSSL exposes.
That direct relationship is why the post-quantum story for Node.js is also the OpenSSL story. As OpenSSL adds native ML-KEM, ML-DSA, and SLH-DSA support, Node.js inherits it. The pacing is set by which OpenSSL version a given Node release line bundles.
This article walks through what Node.js supports for post-quantum cryptography in 2026, how the OpenSSL relationship constrains the timeline, and what application developers can do today.
How Node.js Cryptography Is Layered
Node.js cryptography lives in three places:
- The
cryptomodule, exposed to JavaScript code - C++ bindings in
src/crypto/*.ccthat call into OpenSSL - A bundled OpenSSL distribution under
deps/openssl/
When a user calls crypto.createHmac('sha256', key), Node.js routes through the C++ binding to OpenSSL's HMAC. When a user creates a TLS server, Node.js's TLS module similarly wraps OpenSSL's TLS implementation.
This means the crypto module supports whatever the bundled OpenSSL supports, plus a layer of ergonomic JavaScript APIs on top.
For broader OpenSSL context, see openssl PQC status 2026.
What Node.js Bundles
Different Node.js release lines bundle different OpenSSL versions:
- Node.js 18 (LTS, Hydrogen): OpenSSL 3.0.x
- Node.js 20 (LTS, Iron): OpenSSL 3.0.x and 3.1.x by patch
- Node.js 22 (LTS, Jod): OpenSSL 3.x with progressive updates
- Node.js 24 and beyond: OpenSSL 3.5+ with native PQC support
The exact OpenSSL version inside a Node.js binary determines what algorithms are accessible. For PQC, the relevant question is whether the bundled OpenSSL has native ML-KEM and ML-DSA support.
Where Node.js Stands on Post-Quantum
The picture for 2026:
| Algorithm | Status in Node.js |
|---|---|
| ML-KEM via OpenSSL native | Available in Node.js builds with OpenSSL 3.5+ |
| Hybrid TLS groups | Inherited from OpenSSL where supported |
| ML-DSA | Following OpenSSL roadmap |
| SLH-DSA | Not directly exposed; available via lower-level APIs |
| FN-DSA | Not exposed |
| HQC | Not exposed |
Direct PQC primitive APIs in crypto | Limited; emerging |
For Node.js applications today, the practical paths to PQC are:
- Run Node.js with a build that bundles OpenSSL 3.5+ and configure TLS to negotiate hybrid groups
- Use a third-party Node.js package (oqs-node bindings, or custom wrappers around liboqs) for PQC primitives outside TLS
- Wait for Node.js to expose direct ML-KEM and ML-DSA APIs in the crypto module
Option 1 is what most production deployments will use as Node.js LTS releases pick up newer OpenSSL.
The OpenSSL Coupling
Node.js's bundled OpenSSL is updated with security releases but not freely upgraded between LTS lines. This means an LTS deployment running Node.js 20 will not gain PQC primitives from OpenSSL 3.5 unless Node.js publishes a security release that bundles a newer OpenSSL.
Node.js maintainers have flexibility here. They can choose to bundle a newer OpenSSL when there is a security or feature need. PQC adoption is a feature need that may justify OpenSSL bumps in LTS lines.
For the underlying algorithm details, see ML-KEM explained.
TLS in Node.js with Hybrid Groups
Node.js TLS configuration goes through tls.createServer() or tls.connect() with a TLS context options object. To negotiate hybrid PQ groups (X25519MLKEM768), the server needs:
- An OpenSSL build that supports the group
- TLS context configuration that enables it
- A certificate that the server can present
If the underlying OpenSSL supports X25519MLKEM768 (either via oqs-provider configured at the OpenSSL level, or natively in OpenSSL 3.5+), Node.js's TLS will negotiate it when the client also supports it. No application-level changes are needed.
For applications running behind a load balancer or reverse proxy, the proxy often handles TLS, so the proxy's configuration determines PQC posture, not Node.js's.
For broader context on hybrid encryption, see hybrid encryption.
Direct PQC APIs in node:crypto
Node.js's crypto module has historically exposed asymmetric primitives via classes like KeyObject, createPrivateKey, createPublicKey, sign, verify. These work for RSA, ECDSA, EdDSA, and similar.
Adding ML-KEM and ML-DSA to this surface requires:
- New algorithm identifiers (kept in sync with OpenSSL EVP_PKEY ids)
- KeyObject support for the new key types
- New methods like
crypto.encapsulate()andcrypto.decapsulate()for KEM operations (because KEM is not the same shape as encrypt/decrypt)
This work is happening through Node.js GitHub issues and pull requests. The pace is set by OpenSSL's release of stable PQC EVP_PKEY APIs.
For algorithm comparison, see ML-DSA vs SLH-DSA.
Third-Party Node.js Packages
Several npm packages provide PQC primitives outside Node.js's built-in crypto:
oqs-node(bindings to Open Quantum Safe's liboqs)pqclean-node(bindings to PQClean reference implementations)- WebAssembly-based PQC packages (slow but portable)
These packages are useful for non-TLS PQC needs. They are not the right answer for high-performance TLS termination, but for application-level signing and KEM operations they work today.
The trade-off is that npm packages depend on native binaries with their own build complexity, or on WebAssembly which is slow for PQC compared to native code.
WebCrypto API and PQC
Node.js implements the WebCrypto API as part of the crypto.webcrypto namespace. WebCrypto is a W3C standard for cryptography in browsers, and Node.js mirrors it for compatibility.
WebCrypto's algorithm naming and parameter shapes are defined by W3C. PQC algorithms are being added to the WebCrypto specification, but the work is still in progress. Browser-side implementations are gating on standardization.
For Node.js applications that want WebCrypto-portable code, the answer for PQC is: not yet, plan for the future. Application code that uses WebCrypto today should isolate PQC to non-WebCrypto APIs and migrate when WebCrypto specs settle.
For a Node.js + WebCrypto perspective alongside native, see openssl PQC status 2026.
Node.js Performance for PQC
Node.js's native crypto routes through OpenSSL, so PQC performance in Node.js is essentially OpenSSL's PQC performance plus a small JavaScript overhead. ML-KEM-768 keypair, encapsulation, and decapsulation each fit within hundreds of microseconds on a modern x86_64 server.
For applications doing high volumes of PQC operations (signing JWTs, validating tokens), the JavaScript overhead matters. Native Node.js crypto APIs minimize the overhead because they are C++ bindings. WebAssembly-based packages add more overhead.
For TLS termination at high scale, Node.js's PQC handshake performance is comparable to other TLS libraries. The CPU cost of ML-KEM is small relative to the network cost of larger handshakes.
For broader migration considerations, see AWS KMS quantum migration.
What's Not in Node.js Yet
To set expectations:
- No first-class
crypto.MLKemorcrypto.MLDsaJavaScript classes (yet) - No PQC support in Node.js LTS lines that pre-date OpenSSL 3.5
- No SLH-DSA exposure in the crypto module
- No hybrid certificate validation
- No PQC support in WebCrypto on Node.js (gating on W3C standardization)
These gaps will close as Node.js LTS lines advance and as OpenSSL's PQC APIs stabilize.
Express, Fastify, and Other Node.js HTTP Frameworks
Express and Fastify, the most-used Node.js HTTP frameworks, do not implement TLS themselves. They run behind Node.js's https module or behind a reverse proxy. The TLS leg is what carries PQC protection.
For a Node.js application running https.createServer with a current Node.js LTS that bundles OpenSSL 3.5+, hybrid TLS groups become available with appropriate configuration. The application code in Express or Fastify does not need to change.
For applications running behind nginx or Caddy as a reverse proxy, the proxy's TLS configuration is what matters. Modern nginx with OpenSSL 3.5 or oqs-provider supports hybrid TLS groups; configuring it there gives PQC protection without touching the Node.js layer.
Worker Threads and Crypto Performance
Node.js's worker_threads module allows offloading CPU-heavy work to separate threads. Cryptography is a natural candidate. PQC operations, while not as CPU-heavy as some classical operations, still benefit from worker thread isolation if the application is doing many of them concurrently.
For applications that sign or verify many JWTs per second with ML-DSA (when available in node:crypto), worker threads with a thread pool can keep the main event loop responsive. The crypto bindings hold the Node.js worker pool internally for OpenSSL calls, but application-managed worker threads add another layer of concurrency.
Memory Management and Cryptographic Hygiene
Node.js's garbage-collected memory model means that cryptographic material in JavaScript Buffers may not be promptly cleared after use. For sensitive material like private keys, applications should:
- Use Buffer.alloc() rather than Buffer.allocUnsafe() to avoid uninitialized memory exposure
- Manually zeroize Buffers holding private keys when done with them
- For long-lived processes, consider routing through HSMs that hold private keys outside Node.js's address space
These hygiene practices apply equally to classical and PQ keys but become more important as PQ private keys are typically larger.
For broader hygiene context, see hybrid encryption.
Comparing Node.js to Deno and Bun
Node.js is not the only JavaScript runtime. Deno and Bun are alternatives that ship their own cryptographic stacks. Their PQC stories:
- Deno: Uses Rust's rustls and Boring (BoringSSL fork) for TLS. PQC support follows those libraries. Deno's standard library exposes WebCrypto plus Deno-specific crypto APIs.
- Bun: Uses BoringSSL directly. PQC support follows BoringSSL.
Applications portable across these runtimes face the same general PQC story: hybrid TLS becomes available as the underlying TLS library supports it. Direct PQC primitives are not yet exposed in WebCrypto, so cross-runtime PQC code today depends on runtime-specific APIs or third-party packages.
Best Practices for Node.js Developers
For Node.js applications adopting post-quantum cryptography:
- Track Node.js LTS releases. Plan to upgrade to a release line that bundles OpenSSL 3.5+ for native PQC support.
- For TLS, configure your reverse proxy or Node.js TLS context to advertise hybrid groups when the underlying OpenSSL supports them.
- For non-TLS PQC primitives, isolate them behind a small abstraction layer using third-party packages today. Migrate to native APIs when they ship.
- Audit your dependencies. JWT libraries, password managers, and other crypto-using packages may have their own PQC roadmaps.
- For CDN-fronted services, PQC may be terminated at the edge (Cloudflare, AWS) before reaching Node.js. Verify the end-to-end posture.
For broader infrastructure context, see Azure Key Vault post-quantum.
Frequently Asked Questions
Can my Node.js server use post-quantum TLS today?
If you are running a Node.js build with OpenSSL 3.5 or later, and your TLS configuration enables hybrid groups, yes. Older Node.js LTS lines do not support PQC TLS without OpenSSL upgrades.
Is there a node:crypto.MLKem class?
Not yet at the time of writing. Direct PQC class APIs in the standard crypto module are being designed but not yet shipped. Track Node.js GitHub issues for progress.
What is the recommended path for production Node.js with PQC?
Use Node.js with OpenSSL 3.5+ for TLS-level PQC. Use third-party packages for application-level PQC primitives. Plan migration to native APIs when they land.
Does Node.js handle PQC certificate validation?
Through OpenSSL's certificate chain validation. As OpenSSL adds PQC certificate support, Node.js inherits it.
Where can I read the Node.js crypto source?
The repository is github.com/nodejs/node. The crypto bindings live in src/crypto/. The bundled OpenSSL is in deps/openssl/.
How does Node.js's crypto compare to Deno's?
Both expose WebCrypto-style and runtime-specific cryptographic APIs. Node.js bundles OpenSSL; Deno uses BoringSSL via Rust. PQC support follows the underlying library in each case. Functionally similar, with subtle API differences.
Can my Node.js Lambda functions use PQC?
AWS Lambda runs your Node.js code in an Amazon-managed runtime. The Lambda runtime's bundled Node.js version determines OpenSSL availability. As AWS updates Lambda runtimes, PQC support arrives.
Are there security advisories for PQC in Node.js?
Node.js publishes security advisories at nodejs.org/en/security. PQC algorithms have been integrated through OpenSSL upgrades, which carry their own advisories. Track both Node.js and OpenSSL security feeds.
Sources
- Node.js repository, github.com/nodejs/node
- Node.js documentation, nodejs.org/docs
- NIST FIPS 203, 204, 205 (post-quantum standards), 2024
- OpenSSL repository, github.com/openssl/openssl
- Open Quantum Safe project, openquantumsafe.org
- WebCrypto API specification, w3.org/TR/WebCryptoAPI
Related Articles
- What is post-quantum cryptography
- ML-KEM explained
- Hybrid encryption
- OpenSSL PQC status 2026
- ML-DSA vs SLH-DSA
Protect Your Data Before Q-Day Arrives
QNSQY's NIST-standardized post-quantum encryption protects files against both current and quantum-era threats.