Skip to content

Passphrase Generator

Passphrase Generator is a client-side web app for creating strong, memorable passphrases from real English words. It uses the browser’s crypto.getRandomValues() API for cryptographic randomness — no passphrase ever leaves the browser. The app runs entirely in the client, making it a zero-trust security tool you can use anywhere.

Try the live demo →

  • Cryptographically Secure Randomness — Words are selected using crypto.getRandomValues(), not Math.random(), ensuring passphrases are suitable for real-world security
  • Entropy-Based Strength Meter — A real-time strength indicator calculates entropy in bits based on the ~1,500-word EFF wordlist, word count, capitalization, and number inclusion
  • Flexible Configuration — Choose 3–12 words, toggle capitalization and digit insertion, and pick from six separator characters (hyphen, period, underscore, exclamation, question mark, space)
  • Show/Hide Toggle — Mask the generated passphrase with bullet characters for over-the-shoulder privacy
  • One-Click Copy — Copy to clipboard with visual confirmation feedback
  • Fully Client-Side — Zero network requests for passphrase generation; everything runs in the browser
  • Animated Dark UI — Floating gradient background with glassmorphism card design, built with Tailwind CSS 4 and shadcn/ui

The core generation logic lives in src/lib/passphrase.ts. A secure random index picks words from the EFF Short Wordlist, then applies the user’s formatting options:

function secureRandomInt(max: number): number {
const array = new Uint32Array(1);
crypto.getRandomValues(array);
return (array[0] as number) % max;
}
export function generatePassphrase(options: PassphraseOptions): string {
const words: string[] = [];
for (let i = 0; i < options.wordCount; i++) {
let word = wordlist[secureRandomInt(wordlist.length)];
if (options.capitalize) word = word.charAt(0).toUpperCase() + word.slice(1);
words.push(word);
}
if (options.includeNumber) {
const position = secureRandomInt(words.length);
words[position] = `${words[position]}${secureRandomInt(10)}`;
}
return words.join(options.separator);
}

Entropy estimation uses log₂(poolSize) per word, adds 1 bit for capitalization, and accounts for digit placement:

WordsCapitalizeNumberApprox. Entropy
4~49 bits (Fair)
6~72 bits (Strong)
8~95 bits (Very Strong)
LanguageTypeScript
UI FrameworkReact 19
StylingTailwind CSS 4, shadcn/ui (New York style)
ComponentsRadix UI primitives (Select, Label, Slot)
IconsLucide React
Runtime & BundlerBun
LintingBiome
DeploymentGitHub Pages via GitHub Actions

The project follows Bun’s HTML-import pattern — the server entry (src/index.ts) serves src/index.html, which imports frontend.tsx as a module. Bun handles bundling, Tailwind compilation, and HMR automatically:

src/
index.ts ← Bun.serve() entry point
index.html ← HTML shell with <script src="./frontend.tsx">
frontend.tsx ← React DOM bootstrap (HMR-aware)
App.tsx ← Main UI: passphrase display, controls, strength meter
lib/
passphrase.ts ← Generation, entropy estimation, strength calculation
wordlist.ts ← ~1,500 EFF Short Wordlist entries
utils.ts ← Tailwind class merge utility (cn)
components/ui/ ← shadcn/ui: Button, Card, Input, Label, Select, Textarea

The custom build.ts script wraps Bun’s build API with a full CLI argument parser, supporting flags like --minify, --sourcemap, and --outdir for production builds.

The source code is available on the project’s GitHub repository.