Password Generator
Generate strong, cryptographically random passwords with customizable length and character sets.
Security
100% Free
Runs in Browser
Preview
Length
Source Code
Toggle the controls below the code to live-edit the initial state values.
password-generator.tsx
import { useState, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Copy, Check, RefreshCw } from "lucide-react";
const CHARS = {
lower: "abcdefghijklmnopqrstuvwxyz",
upper: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
numbers: "0123456789",
symbols: "!@#$%^&*()_+-=[]{}|;:,.<>?",
};
function calcStrength(password: string): { label: string; color: string; score: number } {
let score = 0;
if (password.length >= 8) score++;
if (password.length >= 12) score++;
if (password.length >= 16) score++;
if (/[a-z]/.test(password) && /[A-Z]/.test(password)) score++;
if (/\d/.test(password)) score++;
if (/[^a-zA-Z0-9]/.test(password)) score++;
if (score <= 2) return { label: "Weak", color: "text-red-500", score };
if (score <= 4) return { label: "Medium", color: "text-yellow-500", score };
return { label: "Strong", color: "text-green-500", score };
}
export default function PasswordGenerator() {
const [length, setLength] = useState(16);
const [options, setOptions] = useState({
lower: true,
upper: true,
numbers: true,
symbols: true,
});
const [password, setPassword] = useState("");
const [copied, setCopied] = useState(false);
const generate = useCallback(() => {
let pool = "";
if (options.lower) pool += CHARS.lower;
if (options.upper) pool += CHARS.upper;
if (options.numbers) pool += CHARS.numbers;
if (options.symbols) pool += CHARS.symbols;
if (!pool) pool = CHARS.lower;
const arr = new Uint32Array(length);
crypto.getRandomValues(arr);
const pw = Array.from(arr, (n) => pool[n % pool.length]).join("");
setPassword(pw);
}, [length, options]);
const copyPw = async () => {
await navigator.clipboard.writeText(password);
setCopied(true);
setTimeout(() => setCopied(false), 1500);
};
const strength = password ? calcStrength(password) : null;
const toggleOption = (key: keyof typeof options) => {
setOptions((o) => ({ ...o, [key]: !o[key] }));
};
return (
<div className="space-y-4">
<div className="flex flex-wrap items-center gap-3">
<span className="text-sm text-muted-foreground">Length</span>
<Input
type="number"
min={4}
max={128}
value={length}
onChange={(e) => setLength(Number(e.target.value) || 8)}
className="w-20"
/>
<input
type="range"
min={4}
max={128}
value={length}
onChange={(e) => setLength(Number(e.target.value))}
className="flex-1 min-w-[100px]"
/>
</div>
<div className="flex flex-wrap gap-2">
{(Object.keys(options) as (keyof typeof options)[]).map((key) => (
<Button
key={key}
variant={options[key] ? "default" : "outline"}
size="sm"
onClick={() => toggleOption(key)}
>
{key === "lower" ? "a-z" : key === "upper" ? "A-Z" : key === "numbers" ? "0-9" : "!@#"}
</Button>
))}
</div>
<Button onClick={generate} className="w-full">
<RefreshCw className="mr-2 h-4 w-4" />
Generate Password
</Button>
{password && (
<div className="relative rounded-lg border bg-muted/50 p-4">
<code className="text-lg font-mono break-all">{password}</code>
<Button
variant="ghost"
size="icon"
className="absolute top-2 right-2"
onClick={copyPw}
>
{copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
</Button>
{strength && (
<div className="mt-3 flex items-center gap-2">
<div className="flex-1 h-2 rounded-full bg-muted overflow-hidden">
<div
className="h-full rounded-full transition-all"
style={{
width: `${(strength.score / 6) * 100}%`,
backgroundColor: strength.label === "Weak" ? "#ef4444" : strength.label === "Medium" ? "#eab308" : "#22c55e",
}}
/>
</div>
<span className={`text-sm font-medium ${strength.color}`}>
{strength.label}
</span>
</div>
)}
</div>
)}
</div>
);
}
Props Playground
2 props
16
Required Libraries
Install the external dependencies used by this tool.
bun add lucide-react react
Shadcn UI Setup
Add the required Shadcn UI primitives to your project.
bun x --bun shadcn@latest add badge button input
Shadcn UI Components
The following primitives are required in your
@/components/ui
directory.
| Component | Import Path |
|---|---|
| badge | @/components/ui/badge |
| button | @/components/ui/button |
| input | @/components/ui/input |
Imports
All import statements used in this tool.
| Source | Exports |
|---|---|
| react | useState, useCallback |
| @/components/ui/button | Button |
| @/components/ui/input | Input |
| @/components/ui/badge | Badge |
| lucide-react | Copy, Check, RefreshCw |
State Management
React state variables managed within this tool.
| Variable | Initial Value |
|---|---|
| length | 16 |
| options | {
lower: true,
upper: true,
numbers: true,
symbols: true,
} |
| password | "" |
| copied | false |
Variables & Constants
Constants and computed values defined in this tool.
| Name | Value |
|---|---|
| arr | new Uint32Array(length) |
| pw | Array.from(arr, (n) => pool[n % pool.length]).join("") |
| strength | password ? calcStrength(password) : null |
Functional Logic
Internal functions that handle the tool's core logic.
| Function | Parameters | Async |
|---|---|---|
| calcStrength() | password: string | No |
| copyPw() | None |
Yes
|
| toggleOption() | key: keyof typeof options | No |
External Resources
Documentation, tutorials, and package details for libraries used in this tool.