Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Zxcvbn Laravel Package

ziming/laravel-zxcvbn

Laravel wrapper for zxcvbn, the realistic password strength estimator. It exposes zxcvbn-php through a simple facade and validation rule, returning scores, guesses, crack times, and actionable feedback so you can enforce stronger passwords in your app.

View on GitHub
Deep Wiki
Context7

Getting Started

ziming/laravel-zxcvbn is a thin Laravel service-provider wrapper around bjeavons/zxcvbn-php, the offline port of Dropbox's zxcvbn password-strength estimator. The release under review (2.4.6) adds a Laravel 13 compatibility constraint plus CI/dependabot housekeeping — there are no API changes, no new features, and no deprecations. Treat this as a maintenance release: safe to take, no code edits required.

composer require ziming/laravel-zxcvbn

On Laravel 11+/12/13 the provider and facade are auto-discovered. For older skeletons, register Ziming\LaravelZxcvbn\LaravelZxcvbnServiceProvider in bootstrap/providers.php (or config/app.php) and alias the facade.

First use case — score a password inside a Form Request:

use Ziming\LaravelZxcvbn\Facades\LaravelZxcvbn;

$result = LaravelZxcvbn::password($this->input('password'))->check([
    $this->input('email'),
    $this->input('name'),
]);

if ($result->getScore() < 3) {
    // reject, surface $result->getFeedback()
}

Where to look first, in order:

  1. The publishable config (php artisan vendor:publish --tag=zxcvbn-config) — check the config key/alias names before you hardcode the facade in a dozen classes.
  2. The facade's underlying class in src/ — it is only a few lines; confirm which methods are proxied and whether check() accepts user inputs.
  3. vendor/bjeavons/zxcvbn-php — this is where Result, Feedback, getScore(), getCrackTimeSeconds() and getSequence() actually live. Almost all your day-to-day work happens against that object, not the wrapper.

Because the release only widened framework support, the real upgrade question is the PHP floor: Laravel 13 raises the minimum PHP version, so run composer why-not ziming/laravel-zxcvbn ^2.4 before bumping if you are still on PHP 8.1/8.2 or Laravel 10/11.

Implementation Patterns

Custom validation rule (the 90% case). Wrap the check in a rule object so it composes with confirmed, min:8, and the rest of your pipeline:

class StrongPassword implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        $userInputs = array_filter([
            request()->input('email'),
            request()->input('name'),
            config('app.name'),
        ]);

        $result = LaravelZxcvbn::password($value)->check($userInputs);

        if ($result->getScore() < 3) {
            $fail($result->getFeedback()->getWarning()
                ?: 'This password is too easy to guess.');
        }
    }
}

Score thresholds as config, not magic numbers. Persist the minimum score (0–4) in config/auth.php or a dedicated config/password.php. Registration, password reset, and profile-update flows drift apart otherwise, and you will want to tighten the threshold without redeploying business logic across five controllers.

Feed user inputs, always. The single biggest quality win is passing email, username, and app name into check() as user inputs. zxcvbn penalises passwords containing them, which is exactly the class of weak password a length-only rule misses.

Two-stage validation: local score + breach check. zxcvbn is an offline entropy heuristic and will happily score Tr0ub4dor&3x! highly even if it appears in every breach corpus. Pair the score gate with a k-anonymity HaveIBeenPwned range query (or a bundled breach list) and reject on either failure. Keep the two concerns in separate rules so failures stay distinguishable in logs.

Feedback as UX, not as validation. Map getScore() to a strength meter client-side (debounced), but always re-run the check server-side. getFeedback()->getSuggestions() is a plain string array; render it under the field and cap it at two or three items.

Testing. The library is deterministic for a given password and user-input set, so assert on the score directly rather than mocking the facade — it is fast enough for unit tests on short strings. Where you do need isolation (e.g. asserting the rule's failure message), LaravelZxcvbn::shouldReceive('password') works, but over-mocking hides real regressions in the score thresholds.

Laravel 13 upgrade path. Because 2.4.6 only widens constraints, the migration is: bump the package, run the suite, and confirm your composer.json require block now resolves to a single zxcvbn version. If you support both Laravel 12 and 13 in a matrix, no conditional code is needed — the wrapper API is identical on both.

Gotchas and Tips

  • Version jump, not a breaking bump. Going 2.3.6 → 2.4.6 is a minor release; Composer's ^2.4 range will pull it silently. Read it as "Laravel 13 support + CI bumps," nothing more. The dependabot PRs (actions/checkout, composer-install, git-auto-commit-action, fetch-metadata) never touch runtime code.
  • The Laravel 13 PR was AI-authored. It is a constraint-widening change and low risk, but it is also unreviewed-by-a-human territory in spirit. Smoke-test one registration and one reset flow after upgrading rather than trusting the green CI badge alone.
  • Watch the PHP floor, not the Laravel ceiling. Widening framework support often accompanies narrowing or raising the PHP requirement. Check composer show ziming/laravel-zxcvbn after install; a surprise PHP 8.3+ floor breaks CI images pinned to older runtimes.
  • Performance is non-trivial. zxcvbn matches against large frequency lists and ranked dictionaries in pure PHP. It is fine for a handful of HTTP requests but ruinous on a per-keystroke endpoint or a bulk backfill. If you need to re-score existing users, do it in queued chunks; if you need live strength hints, do them client-side and validate only on submit.
  • getCalcTime() breaks array equality. toArray() on the result includes calculation timing, so snapshots and assertSame against a full array fail intermittently. Assert on getScore() and getFeedback()->getWarning() instead.
  • Zero score means "empty or trivially guessable." An empty string scores 0 with no warning in some versions — guard with required|min:8 before the strength rule so users don't see a blank feedback message.
  • Feedback is English-only. There is no translation layer in the wrapper or the underlying library; if you ship a localised UI you must map warning strings to your own keys. Warnings are stable-ish identifiers but not enum-backed — match on the score for logic, on the warning only for display.
  • userInputs must be an array of scalars. Passing an Eloquent model or a nested array silently degrades the penalty calculation (or throws inside the matcher). array_filter() your inputs and cast to string.
  • Don't log the password. Debugging a surprising score tempts you to Log::debug($result); the result includes the matched sequence, which can embed fragments of the password. Log the score and the warning only.
  • Extension point: bind your own instance. The facade resolves from the container, so you can swap in a pre-configured Zxcvbn (custom ranked dictionaries, e.g. your product's brand terms) via a service provider binding. That is the cleanest way to teach the estimator your domain vocabulary without touching the package.
  • Pin and audit. This is a low-churn package that accepts automation PRs readily. Pin a minor range, and re-read release notes for future majors — the wrapper's thinness means breaking changes here will come from upstream bjeavons/zxcvbn-php, not from Laravel.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus