Password Strength Checker and Meter Code

A strong password is one an attacker cannot guess within a sensible number of tries. Length matters most, then avoiding common passwords, words, keyboard runs and dates. Type a password below for an offline estimate of guesses and crack time, then copy a ready strength meter with a show password toggle for your own signup form.

What current NIST guidance asks of signup forms
RuleNIST SP 800-63B
Minimum length15 characters when the password is the only factor; 8 when used with another factor
Maximum lengthAllow at least 64 characters
Composition rules (must include a symbol...)Do not impose them
Forced periodic changesDo not require them; force a change only after a compromise
BlocklistReject common, expected or breached passwords
Paste and password managersAllow them

Updated

The checker splits your password into the pieces an attacker would try first and multiplies the guesses each piece needs. Nothing you type leaves this page. Below it are two strength meters you can paste into a signup form, one for React with Tailwind and one in plain JavaScript.

Strength meter code

React + Tailwind strength meter with show password

A controlled password field with a show and hide button, a four-step bar, a rules checklist and a live text label for screen readers.

import { useId, useState } from "react";

const COMMON = ["password", "123456", "12345678", "qwerty", "111111", "letmein", "iloveyou"];

function score(pw) {
  if (!pw) return 0;
  if (COMMON.includes(pw.toLowerCase())) return 0;
  let s = 0;
  if (pw.length >= 8) s++;
  if (pw.length >= 12) s++;
  if (pw.length >= 15) s++;
  if (/[a-z]/.test(pw) && /[A-Z0-9]/.test(pw) && /[^a-zA-Z0-9]/.test(pw)) s++;
  if (/(.)\1{2,}|0123|1234|abcd|qwer/i.test(pw)) s = Math.max(0, s - 1);
  return Math.min(4, s);
}

const LABELS = ["Too weak", "Weak", "Fair", "Good", "Strong"];
const COLORS = ["bg-red-500", "bg-red-500", "bg-amber-500", "bg-lime-500", "bg-green-600"];

export function PasswordField({ minLength = 15 }) {
  const id = useId();
  const [pw, setPw] = useState("");
  const [show, setShow] = useState(false);
  const s = score(pw);
  return (
    <div className="max-w-sm space-y-2">
      <label htmlFor={id} className="block text-sm font-medium">Password</label>
      <div className="flex rounded-lg border border-gray-300 focus-within:ring-2 focus-within:ring-blue-500">
        <input
          id={id}
          type={show ? "text" : "password"}
          autoComplete="new-password"
          minLength={minLength}
          maxLength={128}
          value={pw}
          onChange={(e) => setPw(e.target.value)}
          aria-describedby={`${id}-hint ${id}-strength`}
          className="w-full rounded-l-lg px-3 py-2 outline-none"
        />
        <button
          type="button"
          onClick={() => setShow(!show)}
          aria-pressed={show}
          className="px-3 text-sm text-gray-600"
        >
          {show ? "Hide" : "Show"}
        </button>
      </div>
      <div className="flex gap-1" aria-hidden="true">
        {[0, 1, 2, 3].map((i) => (
          <div key={i} className={`h-1.5 flex-1 rounded ${i < s ? COLORS[s] : "bg-gray-200"}`} />
        ))}
      </div>
      <p id={`${id}-strength`} aria-live="polite" className="text-sm">
        {pw ? `Strength: ${LABELS[s]}` : ""}
      </p>
      <p id={`${id}-hint`} className="text-xs text-gray-500">
        Use at least {minLength} characters. A few random words works well.
      </p>
    </div>
  );
}

Plain HTML and JavaScript meter

The same idea with no framework. Paste it into any page; the script only touches elements inside the wrapper.

<div class="pw">
  <label for="pw">Password</label>
  <div class="pw-row">
    <input id="pw" type="password" autocomplete="new-password" minlength="15" aria-describedby="pw-msg">
    <button type="button" id="pw-toggle" aria-pressed="false">Show</button>
  </div>
  <meter id="pw-meter" min="0" max="4" low="2" high="3" optimum="4" value="0"></meter>
  <p id="pw-msg" aria-live="polite"></p>
</div>
<style>
  .pw { font: 15px system-ui, sans-serif; max-width: 320px; }
  .pw-row { display: flex; gap: 6px; margin: 4px 0 8px; }
  .pw input { flex: 1; padding: 8px; border: 1px solid #ccc; border-radius: 8px; }
  .pw button { padding: 0 12px; border-radius: 8px; border: 1px solid #ccc; background: #fff; }
  .pw meter { width: 100%; height: 10px; }
</style>
<script>
  (function () {
    var input = document.getElementById("pw");
    var toggle = document.getElementById("pw-toggle");
    var meter = document.getElementById("pw-meter");
    var msg = document.getElementById("pw-msg");
    var labels = ["Too weak", "Weak", "Fair", "Good", "Strong"];
    function score(pw) {
      var s = 0;
      if (pw.length >= 8) s++;
      if (pw.length >= 12) s++;
      if (pw.length >= 15) s++;
      if (/[a-z]/.test(pw) && /[^a-z]/.test(pw)) s++;
      if (/(.)\1{2,}|1234|qwer|password/i.test(pw)) s = Math.max(0, s - 2);
      return Math.min(4, s);
    }
    input.addEventListener("input", function () {
      var s = score(input.value);
      meter.value = s;
      msg.textContent = input.value ? "Strength: " + labels[s] : "";
    });
    toggle.addEventListener("click", function () {
      var showing = input.type === "text";
      input.type = showing ? "password" : "text";
      toggle.textContent = showing ? "Show" : "Hide";
      toggle.setAttribute("aria-pressed", String(!showing));
    });
  })();
</script>

Why length beats complexity

Each extra character multiplies the number of possible passwords. Adding one random lowercase letter multiplies it by 26, while swapping an a for @ in a word adds almost nothing, because attackers apply those swaps automatically.

That is why the estimate rewards long passphrases. Four unrelated words can reach the strongest band while staying easy to type, as long as they are not a famous phrase or song lyric.

Building a meter people trust

A good meter gives feedback that matches the server's rules exactly. If the meter says strong and the server then rejects the password, people stop trusting both. Keep the rules in one place and show the same messages in each.

Announce changes politely with aria-live so screen reader users hear the result without losing their place, and never rely on colour alone: pair the bar with a text label such as Weak or Strong.

How it works

  1. Type a password. The estimate updates with each key and never leaves your browser.
  2. Read the score from very weak to very strong, the estimated number of guesses and the time to crack it in four attack scenarios.
  3. See which parts were matched as common passwords, words, keyboard runs, sequences, repeats or years, with a warning for each.
  4. Copy the React or plain JavaScript meter for your own form. Both include a show password button and announce changes to screen readers.

Tips

Frequently asked questions

Is it safe to type my real password here?

The check runs entirely in your browser and the page makes no network request with what you type. Even so, the safest habit is to test a password with the same shape as your real one, not the real one.

How accurate is the crack time?

It is an estimate. The checker uses short built-in lists of common passwords and words, so a password built from a less common word can score higher here than it deserves. The four scenarios assume typical attack speeds, from a rate-limited login form to a stolen database with a fast hash. Real attackers also use leaked password lists and rules that are far larger than anything a web page can ship.

Should my signup form require a symbol and a number?

Current NIST guidance says no. Composition rules push people toward predictable patterns like Password1!, which pass the rule and still fall to guessing. A length minimum plus a check against common and breached passwords does more for security.

Why does my form need a show password button?

Masked fields cause typos, especially on phones, and typos lead to lockouts and password resets. A toggle lets people check what they typed. Use a real button with a clear label and keep the field type switching between password and text.

Does the meter code check passwords against breaches?

No. The meters score length, variety and a few obvious patterns in the browser so people get quick feedback. The real gate should be on your server: enforce the minimum length and reject passwords found in breach lists there.

Related: API key generator, Hash generator, Password reset email template, How to add a contact form, HTML accessibility checker.

Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.

More in Free Tools

We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.

Product

Who It's For

Features

Resources

Company

View Sitemap