crypto-random-string

Generate cryptographically strong random strings for IDs, slugs, salts, and secrets

Library
npm
v6.0.0
589stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
54/100Fair
Development Activity40
Maintenance36
Community52
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
77/100Good
Architecture75
Code Quality88
Innovation55
Learning Curve90

crypto-random-string is a focused, single-purpose npm utility from Sindre Sorhus’s collection of small JavaScript modules. It generates cryptographically strong random strings using the Web Crypto API’s crypto.getRandomValues, making it suitable for producing identifiers, slugs, salts, PIN codes, fixtures, and other values where predictable output would be a problem.

The library works identically in Node.js and browsers thanks to its reliance on the standard Web Crypto API rather than Node-specific crypto bindings. It ships with several built-in character sets (hex, base64, url-safe, numeric, distinguishable, ascii-printable, alphanumeric) as well as support for fully custom character sets, including characters outside the Basic Multilingual Plane such as emoji.

What You Get

  • A single default export function that takes {length, type} or {length, characters} and returns a random string
  • Seven built-in character-set types: hex (default), base64, url-safe, numeric, distinguishable, ascii-printable, and alphanumeric
  • Support for fully custom character sets via the characters option, with correct handling of characters outside the Basic Multilingual Plane (e.g. emoji)
  • A rejection-sampling algorithm that discards out-of-range random values so output stays uniformly distributed regardless of character-set size
  • Automatic chunking of crypto.getRandomValues calls for strings longer than the API’s 65,536-byte-per-call limit
  • Full TypeScript type definitions with mutually-exclusive type/characters options enforced at the type level via type-fest’s MergeExclusive

Common Use Cases

  • Generating unique identifiers or slugs for database records or URLs
  • Creating cryptographic salts for password hashing
  • Producing short, human-typeable codes (the distinguishable set) for device-pairing or verification flows
  • Generating nonce values for Content-Security-Policy headers using the alphanumeric set
  • Creating strong passwords using the ascii-printable character set
  • Populating test fixtures that need random but well-formed string data

Under The Hood

Architecture The module is a single index.js file with no internal layering: a small set of pure helper functions (fillWithRandomValues, randomBytes, generateForCustomCharacters) feed into one exported default function that validates its options object and dispatches to either the custom-character-set path or a direct byte-encoding path (hex/base64). There is no class hierarchy, no dependency injection, and no external state — every call is independent and the only shared module-level state is the static characterSets Map and allowedTypes Set used for dispatch. Because the surface area is a single function, a change to the core rejection-sampling loop in generateForCustomCharacters would affect every non-hex/base64 code path simultaneously.

Tech Stack The package targets modern JavaScript runtimes (Node.js >=22 per engines) and is published as a native ESM module ("type": "module") with no build step — the published index.js is the source file. Its only runtime dependencies are uint8array-extras (for base64/hex encoding of Uint8Arrays) and type-fest (for the MergeExclusive utility type used only in the .d.ts declarations, so it has no runtime cost). Development tooling is Sindre Sorhus’s standard combination of xo (lint), ava (test runner), and tsd (type-definition testing), with no bundler since the package ships ESM source directly.

Code Quality Testing is thorough for a package this size: test.js covers every character-set type, boundary conditions on rejection sampling at exact power-of-two thresholds, uniform-distribution checks via statistical sampling, correct handling of astral-plane characters, behavior past the 65,536-byte crypto.getRandomValues chunking limit, and a full suite of input-validation error cases (non-integer length, conflicting options, oversized character sets, unknown types). Error handling is explicit and typed (TypeError with descriptive messages) rather than silent failures. There is no dedicated CI config visible in the cloned tree beyond the .github directory, but the test script chains xo && ava && tsd so linting, runtime tests, and type tests all gate a passing run.

What Makes It Unique The implementation’s distinguishing detail is its rejection-sampling approach to unbiased character selection: rather than using value % characterCount, which biases low character-set indices whenever the modulus doesn’t evenly divide the entropy range, it computes a validSelectorCount cutoff and discards any sampled Uint16 value at or above it before applying the modulo. This keeps the output uniformly distributed for arbitrary character-set sizes up to 65,536, a correctness detail many hand-rolled random-string generators get wrong. It also correctly measures and slices by Unicode code point rather than UTF-16 code unit, so custom character sets containing emoji or other astral-plane characters produce strings of the exact requested length.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search