← Back to Blog

Node.js crypto Module: Post-Quantum Algorithm Status

Node.js crypto Module: Post-Quantum Algorithm Status - QNSQY post-quantum encryption guide

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 crypto module, exposed to JavaScript code
  • C++ bindings in src/crypto/*.cc that 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:

AlgorithmStatus in Node.js
ML-KEM via OpenSSL nativeAvailable in Node.js builds with OpenSSL 3.5+
Hybrid TLS groupsInherited from OpenSSL where supported
ML-DSAFollowing OpenSSL roadmap
SLH-DSANot directly exposed; available via lower-level APIs
FN-DSANot exposed
HQCNot exposed
Direct PQC primitive APIs in cryptoLimited; emerging

For Node.js applications today, the practical paths to PQC are:

  1. Run Node.js with a build that bundles OpenSSL 3.5+ and configure TLS to negotiate hybrid groups
  2. Use a third-party Node.js package (oqs-node bindings, or custom wrappers around liboqs) for PQC primitives outside TLS
  3. 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() and crypto.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.MLKem or crypto.MLDsa JavaScript 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:

  1. Track Node.js LTS releases. Plan to upgrade to a release line that bundles OpenSSL 3.5+ for native PQC support.
  2. For TLS, configure your reverse proxy or Node.js TLS context to advertise hybrid groups when the underlying OpenSSL supports them.
  3. For non-TLS PQC primitives, isolate them behind a small abstraction layer using third-party packages today. Migrate to native APIs when they ship.
  4. Audit your dependencies. JWT libraries, password managers, and other crypto-using packages may have their own PQC roadmaps.
  5. 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

  1. Node.js repository, github.com/nodejs/node
  2. Node.js documentation, nodejs.org/docs
  3. NIST FIPS 203, 204, 205 (post-quantum standards), 2024
  4. OpenSSL repository, github.com/openssl/openssl
  5. Open Quantum Safe project, openquantumsafe.org
  6. WebCrypto API specification, w3.org/TR/WebCryptoAPI

Related Articles

Protect Your Data Before Q-Day Arrives

QNSQY's NIST-standardized post-quantum encryption protects files against both current and quantum-era threats.

Try QNSQY