A collection of runtime-agnostic cryptographically-secure utilities.
unsecure is a collection of runtime-agnostic cryptographically-secure utilities. (ba dum tss 🥁)
Zero dependencies, built on the Web Crypto API, one module per subpath so a CDN import ships only what you use, and one typed error for everything that can go wrong.
Documentation: unsecure.s94.dev
# ✨ Auto-detect (supports npm, yarn, pnpm, deno and bun)
npx nypm install unsecure
Runs on Node.js ^22.12 or >=24, and on any runtime with Web Crypto (Bun, Deno, Cloudflare Workers, browsers).
import { argon2Hash, argon2Verify, hmacVerify, totpVerify, uuidv7 } from "unsecure";
// Store and check a password (argon2id, OWASP defaults, PHC string)
const stored = await argon2Hash(plaintext);
const ok = await argon2Verify(stored, submitted);
// Verify a webhook signature in constant time; a missing header is `false`, never a throw
const valid = await hmacVerify(secret, body, request.headers.get("x-signature"));
// Check a 2FA code; replay is refused when you pass back the last accepted step
const result = await totpVerify(secret, code, { lastAccepted: user.lastOtpStep });
// A time-ordered identifier
const id = uuidv7();
Every module is also its own entry point:
import { hkdf } from "https://esm.sh/unsecure/hkdf";
import { base64Parse } from "https://esm.sh/unsecure/utils";
| Module | Functions | Docs |
|---|---|---|
unsecure/hash, unsecure/hmac |
hash, hmac, hmacVerify, importHmacKey |
Hashing & MAC |
unsecure/hkdf |
hkdf, importHkdfKey |
Key derivation |
unsecure/argon2 |
argon2, argon2Hash, argon2Verify, argon2NeedsRehash |
Password hashing |
unsecure/otp |
hotp, hotpVerify, totp, totpVerify, generateOTPSecret, otpauthURI |
One-time passwords |
unsecure/uuid |
uuidv4, uuidv7, createUUIDv7Generator, uuidv7Timestamp, isUUIDv4, isUUIDv7 |
UUID |
unsecure/generate, unsecure/compare, unsecure/entropy |
secureGenerate, secureCompare, entropy |
Secrets |
unsecure/sanitize |
sanitizeObject, sanitizeObjectCopy, safeJsonParse |
Sanitize |
unsecure/random |
createSecureRandomGenerator, secureRandomNumber, secureRandomBytes, secureShuffle, randomJitter |
Random |
unsecure/utils |
hexStringify / hexParse, base64Stringify / base64Parse, base32Stringify / base32Parse, Hex, Base64, Base32 |
Codecs |
unsecure/errors |
UnsecureError |
Errors |
UnsecureError with a machine-readable code; branch on the code, not the message.secureCompare, hmacVerify, hotpVerify, totpVerify, argon2Verify) never throw on untrusted input. They return false; a throw means your own configuration is wrong.Looking for JWT, JWS, JWE or JWK? That is intentionally not here. unjwt covers the whole JOSE toolset with the same runtime-agnostic, Web Crypto approach.
Upgrading from an earlier release? The docs keep the migration guides.
Inspired by DeepSource Corp work.