A small, fully client-side passphrase generator. It strings together random words from the EFF Diceware long wordlist (7,776 words) and, optionally, sprinkles in random digits and symbols — producing passwords that are strong and readable.
Nothing is sent anywhere. All randomness comes from the browser's
crypto.getRandomValues (a CSPRNG), and the app makes no network requests
except loading its own code and font.
- Words, chosen randomly, beat character soup you can remember. A passphrase of 5–6 random words has enormous entropy while staying typeable.
- Entropy is measured honestly. The strength number is the entropy of the
generation process (
words × log₂(7776)plus any random digits/symbols), not a guess based on the final characters. Deterministic touches like capitalising the first letter add readability but zero entropy, and the app says so. - No look-alike characters. The digit pool excludes
0and1so they are never confused withOandl/I.
npm install
npm run dev # start the dev server (prints a local URL)
npm run build # type-check + production build into dist/
npm run preview # preview the production buildRequires Node 18+.
Two options.
This repo ships with .github/workflows/deploy.yml.
- Create a repo on GitHub and push this project to the
mainbranch. - In the repo, go to Settings → Pages → Build and deployment and set Source to GitHub Actions.
- Every push to
mainbuilds the site and publishes it. Your URL will behttps://<username>.github.io/<repo-name>/.
npm run buildThen publish the generated dist/ folder however you like (e.g. push it to a
gh-pages branch, or point Pages at a /docs copy).
vite.config.tsusesbase: "./"(relative asset paths), so the build works at any sub-path — you don't need to hardcode your repo name.
src/
├─ data/effWordlist.ts the 7,776-word EFF list
├─ lib/
│ ├─ crypto.ts CSPRNG helpers (unbiased random int, pick)
│ ├─ generate.ts passphrase assembly + character pools
│ ├─ entropy.ts entropy math + strength bands
│ ├─ format.ts crack-time estimate + human-readable durations
│ └─ types.ts shared types
├─ hooks/usePassphrase.ts options + current passphrase state
├─ components/
│ ├─ Generator.tsx orchestrates the three panels below
│ ├─ PassphraseDisplay.tsx the result, copy, and regenerate
│ ├─ StrengthMeter.tsx crack time + entropy bar
│ ├─ Controls.tsx word-count slider + toggles
│ └─ Toggle.tsx reusable switch
├─ App.tsx page shell
└─ index.css theme tokens + all styles
The estimate assumes a fast offline attack at one trillion guesses/second — deliberately pessimistic. Against a properly slow password hash (bcrypt, Argon2), a real attacker is far slower, so anything that looks strong here is stronger in practice. The number is a teaching aid, not a guarantee.
The EFF wordlist is provided by the Electronic Frontier Foundation under CC-BY-3.0. Do whatever you like with the rest.