saritasa/laravel-fluent-validation
A Laravel package that adds fluent, chainable validation rule builders, letting you define complex validation logic in expressive PHP instead of long arrays or strings. It simplifies custom rules and keeps validators readable, reusable, and easy to maintain.
Architecture fit. The package is a developer-ergonomics layer, not a runtime component. Laravel validation is fundamentally array/string based ('email' => 'required|email|max:255' or ['required','email']); complex rule sets involving sometimes, required_if, bail, nested wildcards (items.*.sku), and Rule:: objects become hard to read and easy to get wrong. A fluent builder that emits the same underlying array sits cleanly alongside FormRequests and Validator::make() — no service provider gymnastics, no container coupling, no middleware, no request-lifecycle hooks. Architecturally this is near-zero-friction.
Integration feasibility. composer require with an MIT license; integration is an afternoon, not a sprint. The caveat is that with 8 stars and 0 dependents, there is no ecosystem signal to lean on — this must be evaluated by reading the source, not by trusting adoption. Expect a small codebase (likely a few hundred LOC), which makes a source audit realistic.
Technical risk.
illuminate/validation v11/v12 and PHP 8.3/8.4 is unverified. There is no stated support matrix.nullable, mis-orders bail, or mishandles an implicit rule produces validation that passes when it shouldn't. A validation library that throws is fine; one that quietly under-validates is a security and data-integrity problem.Key questions.
sometimes, required_if/exclude_if, bail, nullable, and implicit rules (accepted, declined) represented?Rule:: objects, or only scalar string rules?array (losing type information) or typed objects? Does it play well with Larastan/PHPStan and IDE completion?Stack fit. Best fit is a Laravel application with heavy FormRequest usage, particularly API resources with 20+ field payloads and rule sets duplicated across store/update variants or across controllers. Poor fit for small CRUD apps where native array syntax is already readable — the DSL would be net overhead.
Migration path — phased and reversible:
app/Support/Validation) pinned to a commit.nullable, sometimes, and conditional rules.Compatibility.
Sequencing.
Maintenance. The decisive operational fact: adopting this means we become the maintainer. Archived upstream means no bug fixes, no Laravel 13 readiness, no security patches, and no one to escalate to. Budget a named owner for a few hours per quarter plus a bump whenever Laravel ships a major. This is cheaper than it sounds because the library is small and its contract — emit an array — is one Laravel changes slowly; breakage will likely be mechanical (signature drift), not semantic.
Support. No vendor. Support is an internal channel plus the fork's README. The bigger support cost is the house dialect: new hires know 'required|email', not our fluent chain. Documentation is the real expense here, not code.
Scaling. Runtime cost is negligible — per-request allocation of a small array. No caching, no shared state, no concurrency concerns. This scales to any request volume. The scaling risk is codebase scale: surface area to maintain and patterns to keep consistent across teams.
Failure modes (ranked):
Illuminate\Validation\Rule or Validator signature changes across a Laravel major. Detectable in CI.Ramp-up. Roughly half a day for a mid-level Laravel developer to use the DSL competently; one to two days for the owner to understand internals well enough to fork and patch. Reversal cost is low and mechanical, which keeps the downside bounded.
TPM recommendation. Given 8 stars, 0 dependents, an archived repo, and a native Rule:: API that already covers most of the gap, do not adopt this as a live dependency. Treat it as a reference implementation: audit it, run a two-week pilot to see whether fluent construction measurably reduces validation defects and review time, and if it does, vendor a trimmed internal helper behind our own tests. Set the kill criterion at the start — if the pilot shows no measurable win, retire it and keep the native syntax.
How can I help you explore Laravel packages today?