sloth-dev-guy/searches
A Laravel package for adding reusable search functionality to your models and queries. Configure searchable fields, run flexible filtered searches, and get clean, query-builder-friendly results without repeating boilerplate code across your app.
What the package is. sloth-dev-guy/searches is a small Laravel/Eloquent helper that accepts an array-style notation (e.g. request query params mapped to an array) and translates it into Eloquent query constraints, letting a controller hand a filter payload to a model instead of hand-writing when() chains. It is a query-filtering utility, not a search engine — it does not add indexing, relevance ranking, stemming, or full-text capability. That distinction matters for scoping: it competes with Spatie Query Builder and hand-rolled filter classes, not with Laravel Scout or Meilisearch.
Architecture fit. Fits natively into an existing Laravel/Eloquent codebase with no new infrastructure: no service, no driver, no queue, no external dependency. For a product surface that needs user-driven filtering on list endpoints (admin tables, catalogs, reporting screens), the conceptual fit is good and the blast radius is small. Where it does not fit: any requirement for relevance-ranked search, faceting, typo tolerance, or cross-model search — those need Scout plus a driver, and this package should not be positioned as a substitute.
Integration feasibility. Technically low-effort — a Composer require plus a trait or filter call in a model. The real cost is not installation but verification: a 0-star, 0-dependent package with a single release dated 2022-08-15 almost certainly has no public test suite signal, no CI badge of note, and no downstream users to have surfaced bugs. Feasible as a time-boxed spike; not feasible as an unreviewed production dependency without reading the source end to end (it is small enough that this is hours, not days).
Technical risk. Ranked:
| Risk | Severity | Notes |
|---|---|---|
| SQL injection via un-whitelisted field/operator names | High | Array-driven query builders must whitelist columns and operators. If it passes keys into where/orderBy/whereRaw unchecked, it is a direct injection surface. Must be confirmed by code review. |
| Abandonment / Laravel version lock | High | Last release Aug 2022 implies a Laravel 9-era constraint. Laravel 11/12 compatibility is unverified; a hard illuminate/* constraint can block framework upgrades across the whole app. |
| Bus factor and security response | High | Effectively one maintainer, no community. No path to a CVE fix or a patch; you fork or you remove. |
| Query cost / DoS via expensive filter combinations | Medium | Unbounded filter arrays on unindexed columns or leading-wildcard LIKE produce table scans; nested/OR combinatorics can explode. Needs request-level limits regardless of package. |
| Behavioral edge cases | Medium | Ambiguous column errors on joins, empty-array semantics (all rows vs no rows), null handling, type coercion of numeric strings. Undocumented; must be pinned by your own tests. |
| Silent wrong results | Medium | Filtering bugs fail quietly — users see plausible but incorrect lists, which is worse than a 500. |
Key questions to answer before any commitment.
whereRaw/orderByRaw anywhere, and with what interpolation?composer.json PHP and illuminate/* constraints? Does it install cleanly on our current and next Laravel target?TPM recommendation. Do not adopt as a core dependency on the strength of the listing alone. The functional gap it fills is real but small — a competent engineer writes a whitelisted QueryFilter class in under a day — and the ownership cost of an unmaintained 0-star package exceeds the build cost. Sanction a 1–2 day spike only if the team wants the array-notation ergonomics; the default decision should be an in-house filter layer or Spatie Query Builder (actively maintained, explicit allowedFilters/allowedSorts whitelisting, which is exactly the safety property this package may lack).
Stack fit. Drop-in for a Laravel monolith or modular Laravel app on Eloquent. No infrastructure, no config beyond a publish step if one exists, no operational surface. Works alongside existing pagination and API resources. It will not compose with Scout — if the product roadmap includes real search later, this package is a stopgap on the filtering path only, and the two can coexist if the boundary is drawn at "filtering = Eloquent, search = Scout."
Migration path. Treat the package as an implementation detail behind our own seam. Define a QueryFilter contract (or a Filterable trait we own) that controllers depend on, and let the package be one adapter behind it. This is the single most important design decision: it converts adoption from a one-way door into a swap. If the package proves unsafe or blocks a Laravel upgrade, we replace one adapter class instead of touching every controller.
Concretely: controller → FilterRequest (validates and whitelists keys) → QueryFilter interface → package adapter. Validation and whitelisting live on our side of the seam, so we are not relying on the package for the security-critical property.
Compatibility. Two gates before merge. First, composer require must resolve on our current PHP and Laravel versions without --with-all-dependencies gymnastics; check whether it pins illuminate/support to ^9.0. Second, a forward test: does it install against our next planned Laravel major? If the constraint is ^9.0 only, we are adopting a dependency that becomes a framework-upgrade blocker within one cycle — that alone can disqualify it. Mitigation if adopted: fork to sloth-dev-guy/searches under our namespace with widened constraints, at which point we own maintenance and the calculus shifts back toward building it ourselves.
Sequencing.
QueryFilter adapter, write contract tests covering empty arrays, invalid keys, nulls, type coercion, joins/ambiguous columns, and large filter payloads.Note the asymmetry: steps 1–3 are roughly the same effort whether we adopt or build. The spike cost is not wasted either way — it produces the test suite and the whitelist spec we need for the in-house option.
Maintenance. Effectively zero upstream maintenance. No releases since August 2022, no visible issue triage, no dependents generating bug reports. In practice we inherit the maintenance: any bug, incompatibility, or security finding becomes our fork's problem. Budget it honestly — small package, but nonzero and permanent, and it lands on whoever owns framework upgrades. Compare against Spatie Query Builder (actively released, broad adoption) where upstream maintenance is real.
Support. No vendor, no SLA, no community channel. Internal support means "the engineer who read the source." Mitigate with a short internal README documenting the whitelist rules, the adapter seam, and the known edge cases — otherwise the knowledge walks out the door with that engineer.
Scaling. Query-layer filtering scales with the database, not with the package, so there is no package-specific scaling story. The scaling risk is entirely in query shape: unindexed filter columns, leading-wildcard LIKE, multi-column sorts, and deep pagination all degrade as tables grow. Guardrails to impose regardless: cap the number of filters and sort keys per request, reject unknown keys at validation, require an index on every whitelisted filter column, restrict LIKE to prefix-anchored patterns where possible, and add slow-query alerting on filtered endpoints. If a list endpoint is expected to exceed roughly low-millions of rows with free-text-style matching, this is the wrong tool and the requirement should route to Scout with a real search backend.
Failure modes. Enumerate and instrument:
composer update failing or, worse, succeeding with changed semantics. Detect with the contract tests in CI.Ramp-up. Low for anyone fluent in Eloquent — the API surface is small, and if the array notation matches how the frontend already serializes filters, it can remove a layer of controller boilerplate. Cost is concentrated in the review and test-writing, not in learning the package. Expect a half-day for a mid-level Laravel engineer to be productive with the internal README in place, and add a day if the README does not exist.
Bottom line for ops. The package introduces no runtime infrastructure and no new on-call surface — its operational cost is concentrated in ownership and upgrade risk, which is precisely where a 0-star, unmaintained dependency is weakest. Adopt only behind an owned adapter seam with a fork-ready posture, or skip it and spend the same spike effort on a 1-day in-house filter class whose maintenance, compatibility, and injection posture we fully control.
How can I help you explore Laravel packages today?