check-password-strength, owasp-password-strength-test, password-validator, and zxcvbn are JavaScript libraries used to evaluate password security, but they approach the problem differently. zxcvbn is the industry standard for entropy-based estimation, analyzing patterns and dictionary matches rather than simple rules. password-validator focuses on schema-based validation, allowing developers to define specific requirements like length and character types. check-password-strength offers a lightweight scoring system based on regex patterns. owasp-password-strength-test is an older implementation based on legacy OWASP guidelines, often considered outdated compared to modern entropy checks.
Securing user accounts starts with strong password policies, but not all validation libraries measure strength the same way. Some check for rules like "must have a symbol," while others estimate how long it would take to crack the password. Let's compare how zxcvbn, password-validator, check-password-strength, and owasp-password-strength-test handle this critical task.
The biggest difference lies in how these libraries calculate strength. zxcvbn uses entropy estimation, meaning it looks for patterns, dictionary words, and common substitutions. The other three primarily rely on regex rules and constraints.
zxcvbn analyzes the password against a large dictionary and common patterns.
import zxcvbn from 'zxcvbn';
const result = zxcvbn('correct horse battery staple');
console.log(result.score); // 4
console.log(result.guesses); // 15000000000
password-validator checks against a schema you define.
import PasswordValidator from 'password-validator';
const schema = new PasswordValidator();
schema
.is().min(8)
.is().max(100)
.has().uppercase()
.has().lowercase()
.has().digits();
const isValid = schema.validate('MyPass1');
console.log(isValid); // true
check-password-strength uses a weighted regex system.
import { checkPasswordStrength } from 'check-password-strength';
const result = checkPasswordStrength('MyPass1');
console.log(result.value); // "Strong"
console.log(result.score); // 3
owasp-password-strength-test applies static OWASP rules.
import owasp from 'owasp-password-strength-test';
const result = owasp.test('MyPass1');
console.log(result.score); // 2
console.log(result.errors); // ["password is too short"]
Flexibility matters when your security policy changes. Some libraries let you tweak the algorithm, while others let you tweak the rules.
zxcvbn allows you to add custom dictionaries.
import zxcvbn from 'zxcvbn';
// Adding custom dictionary
const result = zxcvbn('password', ['companyname']);
// Score will drop because 'companyname' is now known
password-validator is fully configurable via chaining.
import PasswordValidator from 'password-validator';
const schema = new PasswordValidator();
schema
.is().min(8)
.has().not().spaces()
.has().uppercase()
.has().symbols();
check-password-strength has limited configuration.
import { checkPasswordStrength } from 'check-password-strength';
// Basic usage without deep config
const result = checkPasswordStrength('123456');
owasp-password-strength-test allows rule configuration.
import owasp from 'owasp-password-strength-test';
owasp.config({
allowPassphrases: true,
minLength: 10,
maxLength: 128
});
Good validation helps users create better passwords without frustration. The quality of feedback varies significantly between these tools.
zxcvbn provides specific warnings.
const result = zxcvbn('password123');
console.log(result.feedback.warning); // "This is a top-10 common password"
console.log(result.feedback.suggestions); // ["Add another word or two"]
password-validator returns validation errors.
const errors = schema.validate('short', { list: true });
console.log(errors); // ["min"]
// You must convert "min" to "Password is too short"
check-password-strength gives a simple label.
zxcvbn but easier to display quickly.const result = checkPasswordStrength('abc');
console.log(result.value); // "Too weak"
owasp-password-strength-test lists missing requirements.
const result = owasp.test('abc');
console.log(result.errors); // ["requires digits", "requires symbols"]
Security libraries must be kept up to date to remain effective. Some of these packages are no longer actively maintained.
zxcvbn is maintained by the community.
password-validator is actively maintained.
check-password-strength has multiple variants.
owasp-password-strength-test is largely unmaintained.
zxcvbn over this tool.You need to ensure passwords resist brute-force and dictionary attacks.
zxcvbn// Reject anything below score 3
if (zxcvbn(password).score < 3) {
throw new Error('Password too guessable');
}
Your policy requires exactly 12 characters, 1 symbol, and no spaces.
password-validatorschema.is().min(12).has().symbols().has().not().spaces();
You just need to prevent users from setting "123456".
check-password-strengthif (checkPasswordStrength(password).score === 0) {
showError('Please choose a stronger password');
}
You are updating an old system that used OWASP standards in 2015.
owasp-password-strength-test (Temporary)zxcvbn ASAP.// Only for legacy compatibility
const result = owasp.test(password);
| Feature | zxcvbn | password-validator | check-password-strength | owasp-password-strength-test |
|---|---|---|---|---|
| Logic | Entropy & Patterns | Schema Rules | Regex Scoring | Static Rules |
| Configurability | Custom Dictionaries | Full Schema Control | Limited | Moderate |
| Feedback | Detailed Suggestions | Rule Errors | Simple Labels | Requirement List |
| Maintenance | Active Community | Active | Varied | Unmaintained |
| Best For | Security Critical | Compliance | Simple Apps | Legacy Support |
For most modern applications, zxcvbn is the superior choice because it measures actual guessability rather than arbitrary rules. A password like Tr0ub4dor&3 looks strong by rules but is weak by entropy — zxcvbn catches this, while the others might not.
Use password-validator when you have strict regulatory requirements that demand specific character types. It gives you full control over the policy definition.
Avoid owasp-password-strength-test for new development. It represents an older era of password security that focused on complexity rather than length and unpredictability.
Final Thought: Password validation should happen on the server too. Client-side libraries improve UX, but never trust them for actual security enforcement.
Choose check-password-strength if you need a simple, lightweight scoring mechanism without the overhead of a large dictionary. It works well for smaller projects or internal tools where basic regex validation is sufficient. Use this when you want a quick score indicator without complex configuration.
Avoid owasp-password-strength-test for new projects as it is largely unmaintained and based on outdated guidelines. Modern security practices favor entropy-based checks over the static rules this package enforces. Only consider this if you are maintaining a legacy system that specifically depends on its original test suite.
Choose password-validator if your project requires strict compliance with specific policy rules, such as corporate security standards. It excels when you need to enforce exact constraints like minimum length, specific symbol counts, or forbidden characters. This package is ideal for forms where you must show specific error messages for each failed rule.
Choose zxcvbn if you need the most accurate security assessment based on entropy and real-world cracking data. It is the best choice for applications where security is critical, as it detects patterns like 'password123' that regex miss. Use this when you want to guide users toward genuinely hard-to-guess passwords rather than just meeting arbitrary rules.
A simple way to check that password strength of a certain passphrase. The library is fully typed.
npm i check-password-strength --save
<script src="https://unpkg.com/check-password-strength/dist/umd.cjs"></script>
<script type="text/javascript">
const passwordStrength = checkPasswordStrength.passwordStrength('pwd123').value; // 'Weak'
</script>
const { passwordStrength } = require('check-password-strength')
// OR
import { passwordStrength } from 'check-password-strength'
console.log(passwordStrength('asdfasdf').value)
// Too weak (It will return Too weak if the value doesn't match the Weak conditions)
console.log(passwordStrength('asdf1234').value)
// Weak
console.log(passwordStrength('Asd1234!').value)
// Medium
console.log(passwordStrength('A@2asdF2020!!*').value)
// Strong
The passwordStrength takes 3 arguments:
password (string): the user passwordoptions (array — optional): an option to override the default complexity required to match your password policy. See below.restrictSymbolsTo (string — optional):
passwordStrength function checks against all characters except for the 26 Latin lowercase letters, 26 uppercase letters, and 10 digits. This includes OWASP-recommended characters, accented letters, other alphabets, and emojis.[${escapeStringRegexp(restrictSymbolsTo)}].Password Default Options
The default options can be required:
const { defaultOptions } = require("./index");
// OR
import { defaultOptions } from 'check-password-strength'
default options:
[
{
id: 0,
value: "Too weak",
minDiversity: 0,
minLength: 0
},
{
id: 1,
value: "Weak",
minDiversity: 2,
minLength: 8
},
{
id: 2,
value: "Medium",
minDiversity: 4,
minLength: 10
},
{
id: 3,
value: "Strong",
minDiversity: 4,
minLength: 12
}
]
To override the default options, simply pass your custom array as the second argument:
You can use an array containing fewer or more than four items to define the levels of trust. However, the first element must have both the minDiversity and minLength parameters set to 0. This means that the first element should always represent a "too weak" option.
The result is an object containing the following values (unless you override the options):
| Property | Desc. |
|---|---|
| id | 0 = Too weak, 1 = Weak & 2 = Medium, 3 = Strong |
| value | Too weak, Weak, Medium & Strong |
| contains | lowercase, uppercase, number and / or symbol |
| length | length of the password |
If you want to translate the value (Too weak → Trop faible), you can translate it based on the return value, or override the defaultOptions option, which will be passed back as the function's return value.
Feel free to clone or fork this project: https://github.com/deanilvincent/check-password-strength.git
Contributions & pull requests are welcome!
I'll be glad if you give this project a ★ on Github :)
options objectKudos to @Ennoriel and his efforts for making v2 and v3 possible!