Skip to content
// EFFECT DAYS 2026

NodeCrypto unstable

Node.js layers for the effect/crypto modules, also used by Bun.

layerDigest runs MD5 and SHA on node:crypto, layerMac runs HMAC on node:crypto, layerKdf adds Argon2id, layerAead runs ChaCha20-Poly1305 on node:crypto, and layerSecureRandom, layerCipher, layerSignature, layerKeyAgreement, and layerKeyWrap run the core WebCrypto layers. Each Node.js layer handles only the algorithms and keys it exists for and hands the rest to the core WebCrypto implementation. Layers that need SecureRandom get it from layerSecureRandom, so no layer here has requirements. layer provides every family at once; provide a family's own layer to pick services selectively.

CryptoKey-backed keys go through Node.js's crypto.subtle, because KeyObject.from(cryptoKey) is deprecated (DEP0204). A CryptoKey must come from the WebCrypto reference: Node.js rejects one from another reference with a TypeError, which is a defect.

10 exports Since v4.0.0 Source

Layers

layer

unstable
Since v4.0.0

Layer that provides every effect/crypto service with the Node.js implementations.

Details

This merges the family layers of this module, so it requires nothing. It keeps the node:crypto implementations of layerDigest, layerMac, layerKdf, and layerAead.

Signature

declare const layer: Layer.Layer<SecureRandom.SecureRandom | Digest.Digest | Mac.Mac | Kdf.Kdf | Aead.Aead | Cipher.Cipher | Signature.Signature | KeyAgreement.KeyAgreement | KeyWrap.KeyWrap>

layerAead

unstable
Since v4.0.0

Layer that provides Aead, running ChaCha20-Poly1305 on node:crypto.

Details

Byte-backed ChaCha20-Poly1305 keys encrypt and decrypt synchronously on node:crypto. AES-GCM runs on crypto.subtle and XChaCha20-Poly1305 on its pure TypeScript implementation. This is Aead.layerWebCryptoWith with a node:crypto implementation, so arguments are checked and errors reported as in Aead.layerWebCrypto. Bun's node:crypto lacks ChaCha20-Poly1305, so on Bun this layer runs the core implementation. Output is identical to Aead.layerWebCrypto. Generated keys come from layerSecureRandom.

Signature

declare const layerAead: Layer.Layer<Aead.Aead>

layerCipher

unstable
Since v4.0.0

Layer that provides Cipher from crypto.subtle on the WebCrypto reference.

Details

This is Cipher.layerWebCrypto with layerSecureRandom, so that Node.js programs take every crypto layer from NodeCrypto. Node.js's crypto.subtle already runs AES-CTR and AES-CBC on OpenSSL.

Signature

declare const layerCipher: Layer.Layer<Cipher.Cipher>

layerDigest

unstable
Since v4.0.0

Layer that provides Digest using createHash from node:crypto.

Details

MD5 and the SHA algorithms run synchronously on node:crypto. On Node.js, crypto.subtle.digest sends each call to the threadpool, which is noticeably slower for small inputs. Output is identical to Digest.layerWebCrypto.

Signature

declare const layerDigest: Layer.Layer<Digest.Digest>

layerKdf

unstable
Since v4.0.0

Layer that provides Kdf, adding Argon2id from node:crypto.

Details

Argon2id runs on argon2 from node:crypto, which needs Node.js 24.7 or later linked against OpenSSL 3.2, or Bun 1.4. Support is checked at call time: on other runtimes, deriving with Argon2id fails with an Unsupported reason. HKDF and PBKDF2 go through Kdf.layerWebCrypto, which keeps them off the event loop.

Signature

declare const layerKdf: Layer.Layer<Kdf.Kdf>
Since v4.0.0

Layer that provides KeyAgreement on Node.js's crypto.subtle.

Details

This is KeyAgreement.layerWebCrypto with layerSecureRandom, so that Node.js programs take every crypto layer from NodeCrypto. CryptoKey-backed keys go through Node.js's crypto.subtle, because KeyObject.from(cryptoKey) is deprecated (DEP0204).

Signature

declare const layerKeyAgreement: Layer.Layer<KeyAgreement.KeyAgreement>
Since v4.0.0

Layer that provides KeyWrap on Node.js's crypto.subtle.

Details

This is KeyWrap.layerWebCrypto with layerSecureRandom, so that Node.js programs take every crypto layer from NodeCrypto. Node.js's crypto.subtle runs AES-KW and RSA-OAEP on OpenSSL. CryptoKey-backed keys go through it, because KeyObject.from(cryptoKey) is deprecated (DEP0204).

Signature

declare const layerKeyWrap: Layer.Layer<KeyWrap.KeyWrap>

layerMac

unstable
Since v4.0.0

Layer that provides Mac using createHmac from node:crypto.

Details

Byte-backed keys sign and verify synchronously on node:crypto, since webhook verification is a server hot path. CryptoKey-backed keys go through Node.js's crypto.subtle, and generated keys come from layerSecureRandom. This is Mac.layerWebCryptoWith with a node:crypto primitive, so output and errors are identical to Mac.layerWebCrypto.

Signature

declare const layerMac: Layer.Layer<Mac.Mac>
Since v4.0.0

Layer that provides SecureRandom from getRandomValues on the WebCrypto reference.

Details

This is SecureRandom.layerWebCrypto, re-exported so that Node.js programs take every crypto layer from NodeCrypto. node:crypto adds nothing here.

Signature

declare const layerSecureRandom: Layer.Layer<SecureRandom.SecureRandom>
Since v4.0.0

Layer that provides Signature on Node.js's crypto.subtle.

Details

This is Signature.layerWebCrypto with layerSecureRandom, so that Node.js programs take every crypto layer from NodeCrypto. CryptoKey-backed keys go through Node.js's crypto.subtle, because KeyObject.from(cryptoKey) is deprecated (DEP0204).

Signature

declare const layerSignature: Layer.Layer<Signature.Signature>