A cryptography library for Gleam targeting both Erlang and JavaScript runtimes.
- Runs on both Erlang and JavaScript (Node.js), wrapping each platform's native crypto APIs for consistent behavior.
- All cryptographic operations delegate to the runtime's implementations (Erlang's
cryptomodule, Node.jscryptomodule). - Inspired by Go's crypto library, the API guides you toward safe defaults and makes dangerous operations explicit.
- Validated against Wycheproof test vectors to catch edge-case vulnerabilities.
Note
Browser JavaScript is not supported. The WebCrypto API is promise-based, which doesn't fit the synchronous FFI model. For browser crypto, see plinth which provides Gleam bindings to WebCrypto using promises.
gleam add kryptos- Erlang/OTP 27 or later for the Erlang target
- Node.js 22 or later for the JavaScript target
Encrypt and decrypt data using AES-GCM:
import kryptos/aead
import kryptos/block
import kryptos/crypto
pub fn main() {
// Generate a random 256-bit key
let assert Ok(cipher) = block.aes_256(crypto.random_bytes(32))
let ctx = aead.gcm(cipher)
// Generate a random nonce (never reuse with the same key!)
let nonce = crypto.random_bytes(aead.nonce_size(ctx))
// Encrypt
let plaintext = <<"hello, world!":utf8>>
let assert Ok(#(ciphertext, tag)) = aead.seal(ctx, nonce:, plaintext:)
// Decrypt
let assert Ok(decrypted) = aead.open(ctx, nonce:, ciphertext:, tag:)
// decrypted == plaintext
}Tip
If you're looking for a higher-level library for simple encryption, check out amaro.
For guidance on choosing cryptographic primitives, see Cryptographic Right Answers.

