Install unsecure

Add unsecure to a project with your package manager and import each function from its module's subpath.

unsecure lives on npm as unsecure. It comes as ES modules with TypeScript types included, and every module has its own entry point, so you only load the parts you import.

#Before you start

A quick check of your setup saves a confusing error later:

  • Node.js: Node.js 22.13 or later (24 or later on the 24 line).
  • Other runtimes: Bun, Deno, Cloudflare Workers and browsers work when they expose the Web Crypto API as the global crypto.
  • Browsers: hashing, HMAC, key derivation and one-time passwords need crypto.subtle, which browsers expose only on HTTPS pages and on localhost.
  • CommonJS: the package ships ES modules only. On the supported Node.js versions, require("unsecure/uuid") still works, because no module uses top-level await.
  • No runtime dependencies: installing unsecure adds one package to your lockfile.

#Install the package

Pick the line for the package manager your project already uses:

# ✨ Auto-detect
npx nypm install unsecure

# npm
npm install unsecure

# yarn
yarn add unsecure

# pnpm
pnpm add unsecure

# bun
bun install unsecure

# deno
deno install npm:unsecure

#Import a module

Import each function from its module's subpath. That way every import line tells you, and your bundler, exactly which module it needs:

import { argon2Hash, argon2Verify } from "unsecure/argon2";
import { hmacVerify } from "unsecure/hmac";
import { uuidv7 } from "unsecure/uuid";

The package exports these subpaths: unsecure/argon2, unsecure/compare, unsecure/entropy, unsecure/errors, unsecure/generate, unsecure/hash, unsecure/hkdf, unsecure/hmac, unsecure/odds, unsecure/otp, unsecure/random, unsecure/sanitize, unsecure/utils and unsecure/uuid.

Without a build step, the same subpaths work from a CDN such as https://esm.sh/unsecure@<version>/uuid, and the browser downloads only that one module. Pin a release in the URL and move the pin when you upgrade; Import from a CDN shows a page that does this. You can also import from the root unsecure, which re-exports every module. A bundler trims that down to what you use, but Node.js and a CDN load all of it, Argon2 included.

#Use the types

The types come in the box, so there's no @types/unsecure to install. Two of them show up all over the API, and they're worth knowing by name:

  • BytesSource: anything a function reads as bytes, which is an ArrayBuffer, a SharedArrayBuffer, or any view over one (Uint8Array, other typed arrays, DataView). Import it from unsecure/utils.
  • UnsecureErrorCode: the union of code values an UnsecureError can carry. Import it from unsecure/errors, and see Errors for what each code means.

#When it fails

Two setup mistakes show up as errors rather than as wrong results:

SituationWhat happens
An import names a subpath the package doesn't export, such as unsecure/base64Node.js throws ERR_PACKAGE_PATH_NOT_EXPORTED and bundlers fail to resolve the import. The codecs live in unsecure/utils; the list above has every subpath.
A browser page served over plain HTTPhash, hmac, hkdf, hotp, totp and their verify functions throw an UnsecureError with code PLATFORM. IDs, random values, Argon2 and the codecs still work. Serve the page over HTTPS.