Skip to content
Devix Open Source

Guide

Getting started

npm install @devix-labs/password-strength
import { createStrengthMeter } from '@devix-labs/password-strength';
import '@devix-labs/password-strength/styles.css';

createStrengthMeter(document.querySelector('#password'), {
  userInputs: [email.value, name.value],
});
<script type="module" src="https://devix.pk/cdn/oss/password-strength@1.0.0/password-strength.min.js"></script>

<input id="password" type="password">
<dx-strength-meter for="password" show-time></dx-strength-meter>

8.4 kB gzipped, against zxcvbn's measured 398 kB.

What it refuses to do

Almost every strength bar scores by counting character classes: a capital, a digit, a symbol, a length. That measures nothing.

estimate('P@ssw0rd1').score;                    // 0 — cracked instantly
estimate('correct horse battery staple').score; // 4

P@ssw0rd1 has all four classes in nine characters and scores full marks on every bar you have ever seen. It is in every wordlist. Pushing people towards it is worse than showing no meter at all, and NIST SP 800-63B has said since 2017 to stop imposing composition rules, check against known-bad passwords, and let length do the work.

What it looks for

A known password, a word with @ for a, a run along the keyboard — including ضصثقفغ on an Arabic layout, which nothing else knows — a sequence, a repeat, a date, a year, and anything the person has already told you about themselves.

estimate('ahmed2019!', { userInputs: ['ahmed@example.com'] });
// score 1, warning 'user-input'

Pass the other fields on your form. An email counts as several separate things, so ahmed, example and the whole address are all checked.

The advice is in their language

English, Arabic and Urdu, out of the box:

createStrengthMeter(field, { locale: 'ar' });
// ضعيفة جدًا — هذه من أكثر كلمات المرور استخدامًا.

This is zxcvbn's three most-reacted open issues — #171 (+30), #154 (+13) and #118 (+15), fifty-eight reactions between them — and its feedback is still hardcoded English. Telling a user in Karachi "Add another word or two" in English tells them nothing.

Your own pack is four lines:

import { EN } from '@devix-labs/password-strength';

createStrengthMeter(field, {
  strings: { ...EN, labels: ['Muy débil', 'Débil', 'Aceptable', 'Buena', 'Fuerte'] },
});

Has it been in a breach?

No estimator can tell you. A password can look strong and still be sitting in a dump, and checking is the one thing NIST actually requires.

createStrengthMeter(field, { breachCheck: true });

The password never leaves the browser. Its SHA-1 is taken locally, the first five hex characters are sent, and the API returns every hash starting with them — about five hundred. The comparison happens on your page. The service cannot tell which of the five hundred you asked about.

A match drops the score to nothing whatever the password looked like. A service that is down is ignored rather than allowed to break your form.

A screen reader is not read a bar chart

The bar is a real progressbar with aria-valuetext, and there is a polite live region — which speaks when the band changes, not on every keystroke. Typing a twenty-seven character passphrase produces fewer than five announcements rather than twenty-seven, and there is a test that counts them.

Colour is never the only signal: the word under the bar says it too.

Where to go next

Updated 15 Sep 2026