Library / SDK
dwolfhub/zxcvbn-python avatar
dwolfhub/zxcvbn-python

zxcvbn-python: Dropbox's realistic password strength estimator, ported for Python

Python implementation of Dropbox's realistic password strength estimator

718 stars86 forksPythonMIT

At a glance

What is it?
zxcvbn-python is a Python port of Dropbox's password strength estimator, scoring a password from 0 to 4 and returning crack time estimates for several attack scenarios. It is the port the original Dropbox developers recommend, and its most useful feature is the user input list that catches a name or a birthdate.
Who is it for?
zxcvbn-python is the right choice for a Python service that needs a password strength policy it can explain to users, particularly when signup forms collect a name, a username or a birthdate that you can feed in as user inputs so the estimator penalises the obvious password.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What a strength estimator is actually for

zxcvbn is a realistic password strength estimator, and the word realistic is the whole design brief. Most strength meters measure the character composition of a password, so `Password1!` scores well while `correct horse battery staple` scores badly, which tells the user nothing useful. zxcvbn instead models how an attacker would actually guess, and the result is a score from 0, described as terrible, to 4, described as great, plus a crack time estimate under several attack scenarios.

zxcvbn-python is the Python implementation of the library created by the team at Dropbox, whose original JavaScript version lives in the dropbox/zxcvbn repository. The README states that while there may be other Python ports available, this one is the most up to date and is recommended by the original developers of zxcvbn at this time. That is an unusual endorsement for a port, and it is the single most decision-relevant sentence in the repository.

The audience is any Python team writing a password field: a signup form, a change-password screen, an admin tool creating credentials for someone else. The library gives a score, feedback with concrete suggestions, and the sequence analysis that explains which part of the password was weak. The README lists the features as a score from 0 to 4, feedback on the password and ways to improve it, time estimates on how long it would take to guess in different situations, and the ability to accept user data to be added to the dictionaries tested against.

What it is not is a hashing library or a credential store. It has no database, no user table, no policy engine. It answers one question about one string.

The API: one function, a score, and a dictionary of results

The usage is a single import and a single call. You pass the password as the first parameter and an optional list of user-provided inputs as the `user_inputs` parameter:

python
    from zxcvbn import zxcvbn

    results = zxcvbn('JohnSmith123', user_inputs=['John', 'Smith'])

    print(results)

The returned dictionary is rich enough to drive a UI directly. It carries the password, the `score`, the `guesses` count, the `guesses_log10`, the `calc_time` as a timedelta, a `feedback` object with a `warning` and a list of `suggestions`, two dictionaries of crack times (`crack_times_display` and `crack_times_seconds`), and a `sequence` entry that breaks the password into its matched parts.

The scenario names are the interesting part, because they encode different attacker models. There is `offline_fast_hashing_1e10_per_second`, which is a stolen hash table cracked at ten billion guesses a second, `offline_slow_hashing_1e4_per_second` for a slower offline hash, `online_no_throttling_10_per_second` for an unthrottled online attack, and `online_throttling_100_per_hour` for a rate-limited one. A password can look fine against one and hopeless against another, which is exactly the point of reporting several.

The `sequence` field shows the reasoning. In the README example the password is split into two dictionary matches, `john` from the `male_names` list and `smith123` from the `passwords` list, with a rank for each, the pattern type, the position in the string, and the guess count contributed by each piece. That trace is what lets an application explain itself without inventing its own rules.

The user_inputs argument is where this library earns its keep

The `user_inputs` parameter is the feature that distinguishes zxcvbn from a generic entropy meter, and it is the reason the README lists accepting user data to be added to the dictionaries as a headline feature.

The mechanism is straightforward. zxcvbn ships frequency lists of common passwords and common names, and your `user_inputs` list, such as a first name, a last name, a company name or a pet's name, is added to the dictionaries that are tested against. The estimator then recognises a password like `JohnSmith123` as a sequence of dictionary matches, with the rank of each word and the guess count it contributes, rather than treating it as a random string of mixed case and digits.

In the README example, passing `user_inputs=['John', 'Smith']` for the password `JohnSmith123` produces a score of 2 and a feedback warning with the suggestions to add another word or two and to note that capitalization does not help very much. The `sequence` shows two dictionary matches, `john` and `smith123`, and the total guess count is a little over two and a half million. The same password scored without that context would look considerably stronger to a naive meter, because it is not in a stock password list.

For a signup form this is the difference between an accurate and a misleading meter. If your application knows the display name, the email local part, the company and the year of birth, passing them in makes the estimate reflect what the attacker would try first.

The second optional argument is `max_length`, which overrides the default maximum password length of 72:

python
    from zxcvbn import zxcvbn

    results = zxcvbn('JohnSmith321', user_inputs=['John', 'Smith'], max_length=88)

The README carries a warning against raising it. It strongly advises against setting `max_length` greater than 72 because it can lead to long processing times and may leave server-side applications open to denial-of-service scenarios. That is a security warning about your own service, and it is worth reading twice before you copy the second example into production.

Custom ranked dictionaries for other languages and your own lists

The dictionary side is extensible. There is a helper function in `zxcvbn.matching` called `add_frequency_lists` that takes a mapping of list names to word lists:

python
    from zxcvbn.matching import add_frequency_lists

    add_frequency_lists({
        'my_list': ['foo', 'bar'],
        'another_list': ['baz']
    })

Two rules are stated in the README and both matter. The lists you add are merged with the current ones, though you can also overwrite the current ones if you wish. And the lists should be ordered by how common the word is, with the most common words first, because the ordering carries information the estimator uses.

That ordering requirement is the interesting constraint. zxcvbn does not just need to know which words appear in a password, it needs to know how likely each word is, since the guess count of a dictionary match depends on the rank of the word in its list. Feed it an unordered list and you get a weaker estimate, not an error.

The stated reason for the feature is to support more languages or to add password dictionaries of your own. For a service with a non-English user base, the stock lists are largely English-oriented, and a localised list of common passwords and names is a meaningful improvement in estimate quality. This is also where the library can be told about a specific context: an internal system whose users all share a company name, a service whose users pick from a small set of products, or a site with a year of birth in the signup form.

The data files live in the `data/` directory at the root of the repository, and the package ships them as part of the distribution.

A command line entry point that pipes into jq

The package installs a console script, registered in the setup metadata as `zxcvbn = zxcvbn.__main__:cli`, so the estimator can be used without writing Python. The README shows the shape, with the password piped in on standard input and the result piped out to jq:

bash
    echo 'password' | zxcvbn --user-input <user-input> | jq

A maximum length argument is available on the command line too:

bash
    echo '<long password>' | zxcvbn --max-length 142

And the module can be executed directly, which is useful when the script is not on the path:

bash
    echo 'password' | python -m zxcvbn --user-input <user-input> | jq

This is more than a convenience. A strength estimator that can be piped into jq is a component you can use in a shell script, in a CI check, or in a password policy test harness, without writing a Python wrapper. The `python -m zxcvbn` form is the one to remember in a container or a restricted environment where console scripts are not installed.

One note on the command line examples: the `<user-input>` placeholder is literal in the README, so a real invocation substitutes the actual value. And the `--max-length 142` example is worth reading against the earlier warning, since the same advice applies here.

The repository has a `bin/` directory at the top level alongside the `zxcvbn/` package, a `tests/` directory, a `pytest.ini`, a `tox.ini` and a `setup.cfg`, so the project is laid out as a normal installable package with its own test configuration.

Version 4.5.0, MIT licensing and a last push in April 2026

The package metadata records the name as `zxcvbn`, the version as 4.5.0, and the licence as MIT, with the LICENSE file at the root named LICENSE.txt. The author is listed as Daniel Wolf, the keywords are zxcvbn, password and security, and the project URLs point at the CHANGELOG.md file in the repository. The download URL in the metadata points at a source tarball for v4.5.0.

On the Python side there is a small inconsistency worth knowing about. The README says the package is tested in Python versions 3.8 to 3.13, while the classifiers in setup.py list 3.8 through 3.12 and stop there. The classifiers also record the intended audience as developers, the licence as the MIT licence, and the natural language as English. The test requirements file shows the same split view of the world, pinning pytest 3.5.0 for Python versions below 3.6 and pytest 7.4.2 for 3.6 and above.

Activity is the part to weigh. The repository has no GitHub releases, so there is no tagged release feed to watch, and the last push to the master branch was on 2026-04-13. That is more than six months before this review, so the project is not currently receiving the kind of regular updates that would let you treat the main branch as moving. In practice that means you are adopting a stable, well-understood version rather than tracking a fast-moving dependency, which is not a bad property for a security-adjacent library, but it does mean you should read CHANGELOG.md before upgrading past what you already run.

The MIT licence is a factual reading of the identifier and not legal advice, but for a library with no network calls and no data collection, the obligations are minimal: keep the copyright notice with substantial portions of the code and ship the licence text.

Editorial conclusion

zxcvbn-python is the right choice for a Python service that needs a password strength policy it can explain to users, particularly when signup forms collect a name, a username or a birthdate that you can feed in as user inputs so the estimator penalises the obvious password. It is the wrong choice if you need a library with a recent release cadence, since the last push was on 2026-04-13 and the package metadata still advertises version 4.5.0, and it is the wrong tool for anything beyond strength estimation, since it stores nothing and hashes nothing. Before adopting, confirm your Python version against the tested range of 3.8 to 3.13, leave max_length at its default of 72 because the README warns that raising it invites denial-of-service exposure, and check the CHANGELOG.md in the repository for what has changed since 4.5.0.

Frequently asked questions

How do I install and use zxcvbn-python?

Install the package with pip, then import the zxcvbn function and pass the password as the first argument, with an optional list of user inputs: `from zxcvbn import zxcvbn` followed by `zxcvbn('JohnSmith123', user_inputs=['John', 'Smith'])`. The result is a dictionary containing a score from 0 to 4, feedback suggestions and crack time estimates.

What is the difference between the Python port and the original zxcvbn?

The original library was written in JavaScript by the team at Dropbox. This repository is a Python implementation of it, and the README states that while other Python ports exist, this one is the most up to date and is recommended by the original developers of zxcvbn at this time.

Why does the README warn against a max_length above 72?

The default maximum password length is 72, and the README strongly advises against setting `max_length` greater than that because it can lead to long processing times and may leave server-side applications open to denial-of-service scenarios.

Official sources

  1. dwolfhub/zxcvbn-python on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dwolfhub-zxcvbn-python.svg)](https://hysenlabs.com/projects/dwolfhub-zxcvbn-python)

Was this useful?