Installation

Install unsecure with any package manager, or import a single module straight from a CDN.

unsecure is published to npm as unsecure.

#Install

# ✨ Auto-detect
npx nypm install unsecure-docs

# npm
npm install unsecure-docs

# yarn
yarn add unsecure-docs

# pnpm
pnpm add unsecure-docs

# bun
bun install unsecure-docs

# deno
deno install npm:unsecure-docs

Or let nypm detect the package manager for you:

npx nypm install unsecure

#Requirements

  • Node.js 22.13 or later on the 22 line, or 24 and later. Any other runtime works as long as the Web Crypto API is available as a global: Bun, Deno, Cloudflare Workers, browsers.
  • ESM only. The package ships pure ECMAScript modules.
  • Zero runtime dependencies.

The only global the library touches is crypto: crypto.subtle and crypto.getRandomValues.

#Subpaths and the barrel

Every module is published twice: once inside the barrel at unsecure, and once as its own entry point at unsecure/<name>. Both hold the same code.

// Barrel — one import site, everything available
import { hash, uuidv7, totp } from "unsecure";

// Subpath — one module per import
import { hash } from "unsecure/hash";
import { uuidv7 } from "unsecure/uuid";
import { totp } from "unsecure/otp";

Which one to use:

SituationImport from
A bundler (Vite, webpack, Rollup, esbuild, Bun)Either. The package is sideEffects: false, so the barrel tree-shakes down to what you use.
A CDN, an import map, or a browser without a build stepThe subpath. A network import of the barrel downloads every module.
You want the import to say which module it came fromThe subpath.

The full list of entry points:

unsecure, unsecure/argon2, unsecure/compare, unsecure/entropy, unsecure/errors, unsecure/generate, unsecure/hash, unsecure/hkdf, unsecure/hmac, unsecure/otp, unsecure/random, unsecure/sanitize, unsecure/utils, unsecure/uuid.

#From a CDN

Each subpath is its own bundle, so the browser downloads only the module named in the URL.

import { uuidv7, createUUIDv7Generator } from "https://esm.sh/unsecure/uuid";
import { hkdf } from "https://esm.sh/unsecure/hkdf";
import { argon2Hash, argon2Verify } from "https://esm.sh/unsecure/argon2";
import { totp, generateOTPSecret } from "https://esm.sh/unsecure/otp";
import { Base64, Base32 } from "https://esm.sh/unsecure/utils";

Warning

Importing https://esm.sh/unsecure — the barrel — over a CDN pulls in every module, Argon2 included. On a page that only needs UUIDs, that is the whole library for one function. Name the subpath.

Pin a version in production, the same as any other CDN import:

import { uuidv7 } from "https://esm.sh/unsecure@0.3.0/uuid";

#Types

Types ship with the package; there is no @types/unsecure. Two type names show up across the API:

  • BytesSource — anything the library will read as bytes: a Uint8Array, any other typed array, a DataView, an ArrayBuffer, or a view backed by a SharedArrayBuffer. Anything else is INVALID_TYPE.
  • DigestReturnAs — how hash, hmac, hkdf and argon2 hand their bytes back: "hex", "base64" (alias "b64"), "base64url" (alias "b64url"), or "uint8array" (alias "bytes").
  • DecodeReturnAs — the narrower set the codecs use when decoding: "string", "uint8array" (alias "bytes").