Passphrase Generator
Overview
Section titled “Overview”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.
Features
Section titled “Features”- Cryptographically Secure Randomness — Words are selected using
crypto.getRandomValues(), notMath.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
How It Works
Section titled “How It Works”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:
| Words | Capitalize | Number | Approx. Entropy |
|---|---|---|---|
| 4 | ✓ | ✓ | ~49 bits (Fair) |
| 6 | ✓ | ✓ | ~72 bits (Strong) |
| 8 | ✓ | ✓ | ~95 bits (Very Strong) |
Tech Stack
Section titled “Tech Stack”| Language | TypeScript |
| UI Framework | React 19 |
| Styling | Tailwind CSS 4, shadcn/ui (New York style) |
| Components | Radix UI primitives (Select, Label, Slot) |
| Icons | Lucide React |
| Runtime & Bundler | Bun |
| Linting | Biome |
| Deployment | GitHub Pages via GitHub Actions |
Architecture
Section titled “Architecture”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, TextareaThe 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.
Source Code
Section titled “Source Code”The source code is available on the project’s GitHub repository.