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

abbasudo/laravel-purity

Laravel Purity is an elegant filtering and sorting package for Laravel Eloquent. Add filter() to any query and let frontend users filter and sort results through simple URL query string parameters, with no extra boilerplate.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Build vs. buy for list/filter UIs. Any roadmap item of the shape "let users search, filter, and sort the records table" is a candidate. Purity replaces the hand-rolled if ($request->has('status')) chains that otherwise get re-written in every controller. PM framing: it converts a recurring 2–5 day per-endpoint chore into a one-line convention, which is the difference between shipping filters for one entity this sprint and shipping them for eight.
  • Scope for admin/dashboard and API-first offerings. The package's value scales with the number of list endpoints you expose. An internal admin panel with 20 index tables, or a public API where customers integrate against your collection endpoints, is where the ROI is legible to non-engineers. A product with three read endpoints is not.
  • Public API grammar as a product contract. Adopting Purity means your query-string syntax becomes ?filters[title][$contains]=x&sort=-created_at, with operator names ($contains, $eq, $notIn, $between) that frontend, docs, SDKs, and customer integrations will hard-code. This is a roadmap-sequencing decision, not just a library pick: it should be locked before you publish API docs or a public SDK, because changing operators later is a breaking change for customers. Treat it as a versioned interface from day one.
  • Feature velocity for frontend-driven exploration. Filtering and sorting can be delivered entirely from the client by composing query strings — no new backend ticket per filter. That enables product experiments (add a "price range" and "in stock" facet to the storefront) as frontend-only work, which shortens the loop between "we think users want this facet" and "we have data on whether they use it."
  • Consistency as a UX decision. One package applied uniformly yields the same filter/sort behavior across every list view, instead of five subtly different implementations. That is a support-ticket and design-system argument, not merely a code-quality one.
  • Relation filtering/sorting support enables cross-entity product surfaces. The 3.2.0 "sort by relations" and nested-relationship fixes mean you can expose "sort vendors by their latest order date" style views without bespoke joins — which is often the difference between a flat list page and a genuinely useful operational dashboard.
  • Livewire compatibility (v2.0.0) matters if your roadmap includes server-driven reactive tables; it keeps filter state in the component rather than forcing a full API layer.
  • Explicitly not a search product. Purity does $contains LIKE matching against declared columns. It is not full-text search, relevance ranking, faceting with counts, typo tolerance, or typo-tolerant autocomplete. If a roadmap item says "search," decide early whether it means filter the list (Purity) or find the thing (Meilisearch/Typesense/Elastic/Scout). Conflating them is the most common way this adoption gets oversold internally and then disappoints.

When to Consider This Package

Adopt when most of these hold:

  • You are on a supported Laravel version and already have (or are standardizing on) Eloquent-based index endpoints. The release history shows deliberate framework tracking — Laravel 9/11/12 compatibility PRs, a v3.3.9 dependency bump for Laravel 13 — so staying current is a maintained path rather than a fork you own.
  • There are many collection endpoints, or a small number that you expect to keep extending. The payoff is per-endpoint boilerplate removed, so it is cumulative.
  • The team is small, or the backend is thin relative to the frontend. The "zero boilerplate" pitch lands hardest where there is no platform team to build a query specification layer.
  • You want the filterable surface declared and reviewed (allowlists, ignored params, renamed fields) rather than implicit. Purity's allowedFilters/ignoredFilters and field renaming are the security-relevant features; they are the reason to prefer this over a bespoke 20-line helper, because a bespoke helper is precisely where someone eventually forgets the allowlist.
  • Your data volumes and access patterns are ordinary indexed-column filtering. Sorts on indexed columns and equality/range filters are fine. Deep pagination over large tables is a separate problem Purity does not solve.
  • MIT licensing is acceptable and you are comfortable with a single-maintainer, community-governed dependency. The 515 stars, steady release cadence, and multi-driver test matrix (MySQL, PostgreSQL, MariaDB handling of LIKE/contains and case sensitivity) are reassuring signals — but 0 dependents means you cannot infer production hardening from a downstream ecosystem. Budget for that honestly: read the source, pin the version, and write your own integration tests covering the filters you actually expose.

Look elsewhere, or build your own, when:

  • You need authorization-aware filtering as a first-class concept — per-tenant scoping, row-level visibility, or filters that must be validated against a policy per field. Purity composes with existing global scopes and policies, but the allowlist is a static declaration; if your access control is dynamic, you will be wrapping it anyway. Note that an escape hatch exists (v3.3.0 lets you swap the filter Resolve class for a custom one), but at that point weigh whether you are still buying or effectively maintaining a fork.
  • The API surface is public and long-lived and you are unwilling to commit to the query-string grammar as a contract. If you need a documented, versioned, semantically-stable filter spec with customer-facing SLAs, define that spec yourself and treat any library as one implementation behind it.
  • You need search relevance, faceted counts, fuzzy matching, or ranking. Wrong tool; use a search service.
  • You need aggregation, reporting, or analytics queries rather than row retrieval.
  • Your architecture puts query construction behind a repository/domain layer that must not read HTTP. Purity intentionally reads the query string from inside the data layer. That is the feature, but it is a legitimate architectural objection, and if your organization has already won that argument, do not relitigate it for a filtering shortcut.
  • The platform is not Laravel, or is a Laravel version the package has not yet tracked.
  • You have exactly one or two list endpoints and no plan for more. A short helper plus an allowlist array is the cheaper total cost of ownership.

Adoption gates worth writing into the ticket: pin the version; explicitly enumerate allowed filters and sorts per model (never default to "everything on the model is filterable" — that is how internal columns leak); confirm driver parity for your production database, since contains/case-sensitivity behavior has been fixed per-driver over several releases; add contract tests for the exact filter strings your frontend sends; document the grammar in the API reference in the same PR that adopts it.

How to Pitch It (Stakeholders)

To executives (one paragraph). We can add filtering and sorting to our list screens and collection APIs with roughly a one-line change per endpoint instead of custom code per screen. It is an MIT-licensed, widely used Laravel library with no infrastructure, no database migrations, and no vendor relationship — it is a code dependency, not a platform bet, and it can be removed without data loss. The business case is delivery speed and consistency: the same filtering behavior everywhere, fewer tickets per new admin view, and facet experiments that a frontend developer can run without a backend sprint. The decision that does need executive awareness is that this standardizes the URL grammar our API exposes. That is a one-way door for public-facing customers, so we should make that call deliberately and document it before we publish an SDK.

To engineering (the honest version). This is a thin request-to-query translator over Eloquent: no migrations, no config you must publish, no background processes. It composes with existing scopes, global scopes, and policies, so it drops into a typical controller without restructuring. The tradeoff is deliberate and small: the data layer now reads the HTTP query string. That is exactly why Post::filter() is one line, and it is the one thing to check against our architecture conventions before we adopt. Two conditions on adoption: (1) every model gets an explicit allowlist of filterable and sortable fields — the package supports this, and we must not treat "all columns" as the default; (2) we write integration tests against the exact query strings the frontend sends, on the database driver we actually run in production, because operator and case-sensitivity behavior is driver-specific and has been patched several times across releases. We pin the version and own the upgrade.

To the frontend and design partners. Filters and sorts become client-composable: you build the query string, the backend applies it, and adding a facet does not require a backend ticket — provided the field is already on the allowlist, so give us the facet list at design time. Agree on the parameter syntax and operator names early and treat them as an API contract; renaming an operator later breaks saved views and any customer integrations.

What to say no to. Do not sell this internally as "search." It is column-scoped filtering with contains/equality/range operators — no relevance ranking, no faceted counts, no typo tolerance. If the roadmap says "search," scope it separately. Promising search and delivering filters is a cheap way to burn credibility on an otherwise good, boring, correctly-sized dependency.

Risk statement for the decision log. Single-maintainer community package, MIT, ~515 stars, active maintenance including framework compatibility through Laravel 13, but no meaningful downstream dependent base to lean on — so our confidence comes from reading the code and our own test coverage, not from third-party adoption. Mitigation: pinned version, allowlists enforced per model, contract tests, and a documented exit path (the surface we depend on is filter()/sort() plus a field whitelist — small enough to replace with in-house code if maintenance stalls).

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings