LocalMode /ui
Security & Privacy

Password Strength Bar

A presentational password/passphrase strength meter — a themed bar + label driven by a caller-computed 0–100 strength score.

Password Strength Bar

The Password Strength Bar renders a themed horizontal bar and label that visualize how strong a password or passphrase is. It is presentational only: your app computes the strength (0100), the label string, and a semantic color token, then passes them in — pairing with deriveEncryptionKey / Web Crypto from @localmode/core in the surrounding key-derivation flow.

No turnkey hook. This primitive does no strength estimation. There is no @localmode/react hook behind it — the app supplies the computed value, label, and color (typically from length/entropy or a zxcvbn-style estimator). The component only renders the state you give it.

When to use it: any password-creation, passphrase, or key-derivation form where you already estimate strength and want a themed meter to surface it.

Preview

Installation

pnpm dlx shadcn@latest add @localmode/ui/security-privacy/password-strength-bar
npx shadcn@latest add @localmode/ui/security-privacy/password-strength-bar
yarn dlx shadcn@latest add @localmode/ui/security-privacy/password-strength-bar
bunx --bun shadcn@latest add @localmode/ui/security-privacy/password-strength-bar

Dependencies

  • Data source: purely presentational — it renders the value (0–100), label, and color you compute (from length/entropy or a zxcvbn-style estimator) and works anywhere; there is no producer hook. Pairs naturally with a @localmode/core deriveEncryptionKey / Web Crypto key-derivation flow, but that is optional.
  • clsx + tailwind-merge — via the shared cn() util (installed automatically as a registry dependency)

Files installed

  • password-strength-bar.tsx — the component
  • lib/utils.ts — the cn() helper (if not already present)

Props

PasswordStrengthBar

Prop

Type

Examples

Caller computes strength

The app owns the estimator. Map your score onto a 0100 value, a label, and a semantic color token:

import { PasswordStrengthBar, type StrengthColor } from '@/components/password-strength-bar';

function estimate(password: string) {
  const classes =
    (/[a-z]/.test(password) ? 1 : 0) +
    (/[A-Z]/.test(password) ? 1 : 0) +
    (/[0-9]/.test(password) ? 1 : 0) +
    (/[^a-zA-Z0-9]/.test(password) ? 1 : 0);
  const lengthScore = Math.min(password.length, 16) / 16;
  return Math.round(lengthScore * 60 + (classes / 4) * 40);
}

export function PasswordField({ password }: { password: string }) {
  const value = estimate(password);
  const color: StrengthColor = value < 40 ? 'error' : value < 70 ? 'warning' : 'success';
  const label = value < 40 ? 'Weak' : value < 70 ? 'Good' : 'Strong';
  return <PasswordStrengthBar value={value} label={label} color={color} />;
}

Pair with key derivation

Estimate strength before deriving an encryption key with @localmode/core:

import { deriveEncryptionKey } from '@localmode/core';
import { PasswordStrengthBar } from '@/components/password-strength-bar';

// 1. Surface strength as the user types
<PasswordStrengthBar value={strength} label={label} color={color} />

// 2. On submit, derive the key (Web Crypto, never leaves the device)
const { key } = await deriveEncryptionKey(password, salt);

Bar only (no label)

<PasswordStrengthBar value={72} color="success" hideLabel />

Customization

The bar is styled entirely with shadcn/ui CSS-variable utilities (bg-muted for the track) so it inherits your theme. The semantic fill/label colors use Tailwind's red / amber / emerald palettes directly — swap those classes in the copied password-strength-bar.tsx to match your design system, or wire them to your own tokens.

Because you own the file, you can also change how color maps to tokens, or add more granular labels (Very weak, Fair, …) — the component never derives the label from value, so your thresholds stay in your code.

On this page