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 Filterable Laravel Package

thejano/laravel-filterable

Laravel Filterable offers a clean, reusable way to filter Eloquent models using query string parameters. Define filters as dedicated classes, keep controllers slim, and compose filters with support for relationships, scopes, validation, and custom logic.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

thejano/laravel-filterable is a model-layer concern: it attaches a trait to Eloquent models and resolves request-driven filter definitions into query-builder constraints. That places it squarely in the repository/query-object layer of a conventional Laravel application — it composes with ->paginate(), eager loading, and scopes, and it does not attempt to own HTTP, serialization, or response shaping. For a Laravel monolith or a Laravel API backend where models are the system of record, the architecture is a natural fit.

It is a poor fit where models are not the query surface: read models backed by Elasticsearch/Meilisearch/Algolia, CQRS projections, or services with hand-built query builders. In those cases the package adds a second, divergent filtering dialect and should be excluded.

Integration feasibility

Integration cost is low and mechanical: composer require, optional config publishing, add the trait to a model, declare filter classes, and the package handles request-to-query translation. A competent Laravel engineer can produce a working pilot in well under a day. The real work is not wiring — it is deciding which columns are filterable and encoding that policy as code rather than convention.

Two feasibility gates must be cleared before commitment:

  1. Version support matrix — confirm declared support for your Laravel and PHP versions. A small package can silently lag a major Laravel release, and a framework upgrade then blocks on a dependency you cannot patch upstream.
  2. Filter surface control — verify that filters are opt-in per model (explicit allowlist), not derived from request keys. Any package that maps arbitrary query-string keys to columns is effectively a SQL injection and index-scan vector. This is the single highest-severity question in the evaluation.

Technical risk

The dominant risk is not code quality but sustainability signal: 75 stars, a low composite score, and a maintainer profile that is very likely a single individual. That is a bus factor of one on a component that will end up in the request path of every list endpoint. Mitigations are cheap (pin the version, vendor the source, prepare a fork) but they must be decided up front, not after an abandonment.

Secondary risks:

  • Behavioral coupling to Eloquent. Filter definitions expressed as query-builder mutations are hard to unit test in isolation and tend to become de facto business logic. Left unmanaged, filtering semantics drift into the model and become invisible to API contracts.
  • Unbounded query cost. Filtering by design multiplies the set of query shapes the database optimizer must handle. Without a governance rule tying each filter to an index, latency regressions appear late and are hard to attribute.
  • Semantic drift on minors. In a pre-1.0-style package, operator semantics, key naming, and null handling can change between minor releases.

Key questions for the vendor/maintainer review

  1. Does the trait require an explicit allowlist of filter names, and what happens on an unknown query-string key — ignore, throw, or pass through?
  2. What is the declared support matrix for Laravel and PHP, and is there CI coverage across those versions?
  3. Does it support operator-typed filters (range, in, like, null) with parameter binding, or does any path concatenate raw SQL?
  4. How does it interact with eager loading and pagination — is there a documented N+1 story?
  5. What is the release history and breaking-change cadence over the last 12 months?
  6. Is there a defined extension point for custom filter logic, or must we fork to add one?
  7. Does it ship tests, and what is coverage on the filter-resolution path specifically?

Integration Approach

Stack fit

Best fit is a Laravel 10+ API backend, models-as-system-of-record, moderate endpoint count, and a team already comfortable with Eloquent. It is a defensible choice when the alternative is hand-rolled scopeFilter methods scattered across models — the package at least centralizes filter definitions and makes the allowlist explicit. It is a weaker choice if the team has already standardized on spatie/laravel-query-builder, which is more widely adopted and therefore better documented, better tested, and lower bus-factor risk.

Migration path

Three realistic entry points, in ascending cost:

  • Greenfield endpoints. Use the package directly for new list endpoints. Zero migration cost, fastest validation of whether the abstraction matches the team's mental model.
  • From hand-rolled scopes. Mechanical per-model conversion: inventory existing scope* methods, express each as a filter definition, delete the scope, add contract tests asserting identical result sets for the same query strings before deleting. Budget roughly half a day per model with a non-trivial filter set.
  • From spatie/laravel-query-builder. Do not do this without a strong, specific reason. The migration is a rewrite of every filter definition and every test that asserts on query strings, and it trades a lower-risk dependency for a higher-risk one. Treat this direction as out of scope unless Spatie's package is blocking something concrete.

Compatibility

Pin the exact version in composer.json rather than floating a caret constraint, given the release cadence and small maintainer base. Record the supported Laravel/PHP combination in the service's README so the next framework upgrade has a named dependency to check.

Sequencing

  1. Spike (1–2 days). Build one endpoint end to end in a sandbox branch. Answer the allowlist question and the operator-injection question from the code, not the README.
  2. Isolation layer (2–3 days). Wrap the package behind a thin internal abstraction — a FilterSet base class or query-object interface that endpoints depend on. This is the highest-leverage step in the whole plan: it converts an abandonment risk into a two-day swap.
  3. Governance (1 day). Write the rule that every filterable column needs a supporting index, and add it to the schema review checklist.
  4. Pilot (1 sprint). Convert 2–3 representative models — one simple, one with joins, one with a high-cardinality column — and measure before/after query plans.
  5. Rollout. Widen model-by-model behind the abstraction, with contract tests committed alongside each conversion.

Operational Impact

Maintenance

Ongoing maintenance load is genuinely low — the package is small and does not need configuration churn. The cost is contingency: assume no upstream fixes for security or framework-compatibility issues. Budget the fork path explicitly. Because the license is MIT, vendoring the source or maintaining an internal fork is legally trivial and should be documented as a runbook step ("if upstream goes quiet for >12 months or blocks an upgrade, fork at the pinned tag"). One engineer should be named as owner.

Support

Community support will be thin at this adoption level — expect to read the source rather than find answers. Internal expertise must therefore be deliberate: whoever completes the spike becomes the reference. Do not let this package be a single person's undocumented knowledge.

Scaling

Two scaling axes matter and both are operational, not library, concerns:

  • Database load. Every new filter is a new query shape. Filters on unindexed or low-selectivity columns will pass code review and then degrade under production data volume. Enforcement mechanism: query-plan review for any new filter on a table above a size threshold, plus a cap on the number of simultaneous filters accepted per request.
  • Request surface. Unbounded filter counts and unbounded page sizes combine badly. Enforce a maximum page size and a maximum filter count at the boundary, independent of the package.

The library itself scales horizontally with the application tier; it introduces no state, no cache, and no async component.

Failure modes

  • Silent over-permission. A filter that maps request keys to columns without an allowlist leaks data (existence oracles on other tenants' rows) or permits expensive scans. Detect via automated tests asserting unknown keys are rejected, plus a static check that the trait is never applied without declared filters.
  • Multi-tenant leakage. If filters are declared on a shared base model, a tenant-scoped column may become globally filterable. Keep tenancy scoping in a global scope that runs regardless of filter declaration, and test it.
  • Upstream abandonment / framework lock. Surfaces as a failed composer update during a Laravel upgrade. Detection: the fork contingency in the runbook; prevention: pinning and the isolation layer.
  • Query-plan regressions. No error, just p95 latency creep. Detection: per-endpoint latency budgets on list routes and a periodic review of slow-query logs filtered to filterable models.
  • Behavioral drift on upgrade. Result sets change subtly after a minor bump. Detection: contract tests asserting result sets for fixed query strings.

Ramp-up

Ramp-up is short by design: a Laravel developer who knows Eloquent is productive in a few hours, and the team-level documentation burden is one page covering the allowlist rule, the index rule, the isolation layer, and the fork runbook. The real ramp-up cost sits with the reviewers — the people who must recognize an unindexed filter or an over-permissive filter set in a pull request. That is a checklist and code-review discipline problem, and it should be treated as the primary onboarding artifact rather than the package's API.

Recommendation. Adopt narrowly and defensively: pin the version, wrap it behind an internal abstraction, apply it to a small pilot first, and treat the fork contingency as a planned option rather than an emergency. If the team is already standardized on spatie/laravel-query-builder, the incremental value here does not justify a migration.

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.
mydnic/volet-feature-board-filament-plugin
wmde/email-address
refinery29/test-util
dees040/laravel-api-responses
teamzac/geocoder
ideatica/config-writer
keaton-php/pipe-dream
jacksonwebservices/laravel-user-suite
maksimru/conditional-laravel-debugbar
gismatul/nova-support-chat
gismatul/laravel-support-chat
networkrailbusinesssystems/oracle-api
alphabalex/messaging-made-easy
rawphp/warp
shootkiran/merobug
narakode/fineauth
numencode/wn-syncops-plugin
ibnnajjaar/mib-global-pay
refinery29/php-cs-fixer-config
parsnick/steak