Why Local, In-Browser Generation Is Safer

It is easy to overlook, but the moment a password is created is one of its most vulnerable. If that happens on someone else's server, you are trusting them completely. Generating locally in your browser sidesteps that trust entirely — and it is worth knowing why.
The problem with server-side generators
When a website generates your password on its server, that password travels across the network and passes through infrastructure you cannot see. Even with HTTPS protecting it in transit, the server itself handled your password in plain form — it could log it, a bug could leak it, or a compromised server could quietly keep a copy. You have no way to verify what happened to it. The only password guaranteed never to leak from a server is one the server never touched.
There is also more infrastructure in the path than the padlock icon suggests. A typical request terminates TLS at a CDN edge, crosses a load balancer, reaches an application server, and may be recorded along the way by request logging, an error-tracking service or a web application firewall — all operated in good faith, none of them under your control, and any of them capable of retaining a request body for weeks. A privacy policy is a promise about behaviour. Local generation is a property of the architecture, which is a different and considerably stronger kind of assurance.
How in-browser generation works
A client-side generator like PassVault runs entirely as JavaScript inside your browser tab. It calls the Web Crypto API — crypto.getRandomValues() — which produces cryptographically secure random bytes using the operating system's own entropy sources. The password is assembled in your device's memory and displayed on screen. No request is sent, because there is no server to send it to.
That function is not a random-looking arithmetic trick. It is backed by the platform's cryptographically secure generator — /dev/urandom on Linux and macOS, BCryptGenRandom on Windows — seeded from hardware and system entropy and designed so that observing past output reveals nothing about future output. The function JavaScript reaches for out of habit, Math.random(), offers none of those properties: it is fast, seeded by nothing secret, and its future output is recoverable from a handful of samples. No password should ever come from it.
Older tools sometimes asked you to wiggle the mouse to 'gather entropy'. That is a relic of an era when operating systems booted with thin entropy pools and browsers had no proper API. On any current system the kernel pool is well seeded long before a page loads, and the browser's generator draws from it directly — the mouse-wiggling step adds nothing but ceremony.
Turning random bytes into characters
Getting random bytes is the easy half. Mapping them onto an alphabet without skewing the result is where generators quietly go wrong. A byte holds 256 values, so picking from 94 characters with byte modulo 94 makes the first 68 characters come up half again as often as the rest — 256 is not a multiple of 94, and the remainder has to land somewhere. The bias is small, but it is real and measurable across many passwords, and it narrows the search an attacker has to perform.
The correct fix is rejection sampling: discard any byte that falls into the incomplete final block and draw a fresh one. It costs a few extra bytes of randomness and guarantees every character in the set is exactly equally likely, which is the assumption the entropy formula depends on. The same care applies to shuffling — a Fisher-Yates shuffle fed by an unbiased index is correct, sorting by random keys is not.
Verify it yourself
The nice thing about local generation is that the claim is testable. Open your browser's developer tools, switch to the Network tab, and generate a few passwords: you will see no outgoing requests. You can even disconnect from the internet and the tool keeps working, because everything it needs already ran on your machine. That transparency is the whole point.
Two further checks take about a minute. View the page source: the site is a static export, so the generation code is ordinary JavaScript you can read rather than a call to an API endpoint. Then load the page, switch the device to airplane mode and keep generating — anything that still works with the radio off is, by construction, not sending your password anywhere.
What local generation does not protect against
Local generation removes the network from the threat model; it does not remove your device. Malware with keyboard or screen access sees the password as it appears, a browser extension holding permission to read page content can lift it out of the DOM, and a screen-sharing call will broadcast it to everyone on the call. So treat a freshly generated value as sensitive on your own machine too: generate it when nobody is looking over your shoulder, move it straight into your password manager rather than a notes app or a chat window, and clear the clipboard afterwards. Once you close the tab the browser holds nothing, which is the intended end state.
The takeaway
A password generated in your browser never crosses the network, so no server can log or leak it. Prefer local, client-side tools — and confirm it yourself by watching the Network tab.
Create a strong password or passphrase in your browser.
More guides

What Makes a Password Strong
Length, randomness and uniqueness — not clever substitutions — are what actually make a password hard to crack. Here's how each one works.

Password Entropy Explained
Entropy is the one number that objectively measures password strength. Learn the formula, what the bits mean and how to read a crack-time estimate.

Passphrases vs Passwords: Which to Use
Random character strings and multi-word passphrases can be equally strong. The difference is where you use them and whether you have to remember them.