sehrgut/eloquery
eloquery is a small Laravel package that adds convenient helpers for building Eloquent queries, aimed at reducing boilerplate when filtering, sorting, and composing database queries in your models.
Architecture fit. Eloquent query building is a core Laravel concern, and eloquery addresses a genuinely common need: translating HTTP query parameters (filter, sort, page, include, q) into a constrained Builder state before execution. Architecturally this belongs in the HTTP-to-domain boundary of a Laravel application — a controller middleware or form-request layer upstream of repositories/services. The package's scope (a single concern, applied to an existing builder instance) is well-shaped for that seam and does not require the application to invert dependencies or adopt a custom query DSL. In principle it fits a conventional Laravel layered architecture without structural change.
Integration feasibility. Integration is mechanically trivial: install, then invoke the package against a builder the application already owns. There is no schema, no service provider configuration of consequence, and no persistence footprint. The real feasibility question is not "can we wire it up" but "should we depend on it" — and on that axis the package fails. It is marked archived, holds 4 GitHub stars, and has 0 dependents. That combination means the code has had essentially no production exposure and no adversarial review, and that no upstream will ever ship a fix. Feasibility is high; suitability is low.
Technical risk. This is a high-risk dependency for its position in the request path:
include-style parameters that are not strictly allow-listed can load relations the caller was never meant to traverse, leaking fields or bypassing policy scoping.Key questions. (1) Does the package enforce allow-listing, or does it accept arbitrary column names and operators? (2) Are eager-loadable relations and the request-parameter namespace configurable, so we can avoid collision with other reserved parameters? (3) Is search a fixed LIKE implementation, or pluggable — and does it parameterize properly? (4) How is paginate bounded — is max page size enforceable by config? (5) Which Laravel/PHP versions does the archived code actually run against today, and does it pass our test suite on our target version? (6) Is there internal appetite to own a fork indefinitely, or is the feature set generic enough to reproduce in-house?
Stack fit. The package assumes a standard Laravel stack with Eloquent and the HTTP request lifecycle — no queue, cache, or event infrastructure required, and no opinion about authentication or tenancy. That neutrality is a plus: it can sit behind any authorization layer as long as policies are applied to the builder before parameters are merged. Two constraints matter: it must run after tenant/authorization scoping so filters cannot widen the result set, and before get()/paginate() so include and sort are honored.
Migration path. Given the archived status, the recommended path is not adoption as a dependency. Two viable alternatives, in order of preference:
laravel-query-builder occupies this exact problem space, is actively maintained, supports Laravel's current majors, and enforces explicit allowedFilters/allowedSorts/allowedIncludes allow-lists by design. Migrating to it costs little because the public contract is conceptually identical: allowed parameter names, then apply.app/Support/QueryParams, add an explicit allow-list configuration, and treat it as first-party code with tests and an owner. This preserves any semantics we've come to rely on while removing the supply-chain liability.If a decision has already been made to pilot it, treat the pilot as a read-only evaluation of its parameter semantics, not a production commitment.
Compatibility. Expect the archived code to have drifted from current Laravel. Deprecations in the query builder, changes to Request access, and PHP type-strictness shifts are the likely break points; these surface immediately in static analysis and a single endpoint's feature test, which is cheap to verify. The compatibility question is less "does it run" than "does it run on the version we'll be on in 18 months" — and the answer, absent a fork, is no.
Sequencing. (1) Extract the desired parameter contract from the package's README into an explicit allow-list spec per endpoint — this artifact is reusable regardless of which implementation we choose. (2) Benchmark against Spatie's package on a representative complex endpoint. (3) Decide adopt-maintined vs. fork-internally; do not carry both. (4) If forking, add tests for allow-list enforcement, eager-load restriction, and page-size clamping before the first endpoint ships. (5) Roll out endpoint-by-endpoint, starting with the least sensitive read API.
Maintenance. This is the decisive factor. An archived package transfers all maintenance to us the moment it blocks a framework upgrade. The code is small enough that ownership cost is a day or two per year — but it is ownership we would be volunteering for on a component that sits in front of every list endpoint, with no upstream to defer to. Contrast with a maintained dependency, where maintenance cost is effectively zero.
Support. There is no support channel: no issue triage, no security advisories, no release cadence. Internal engineers will be the only source of answers, and only after reading the source. Onboarding documentation must be written by us, not read from upstream.
Scaling. The package is not a throughput bottleneck — query-parameter merging is microseconds against a database round trip. Scaling risk is indirect and lives in the queries it produces: sorts on unindexed allow-listed columns, LIKE '%term%' searches that cannot use indexes, and unbounded page sizes that let a caller request 100k rows. Enforce a max page size in configuration and restrict sortable columns to indexed ones; both are policy controls we must add regardless of implementation.
Failure modes. Ranked by likelihood and blast radius:
Schema::hasColumn-style dynamic checks.Ramp-up. Developer ramp-up is a non-issue — the API surface is a handful of methods and an engineer is productive in under an hour. The organizational ramp-up is the real cost: someone must own the fork, the allow-list policy must be documented and reviewed per endpoint, and the team must internalize that a query-parameter feature is an input-validation surface, not a convenience. Budget for that governance, not for training.
Recommendation. Do not adopt eloquery as a production dependency. Its archived status, negligible community signal, and position in the request path combine into a liability that outweighs the modest convenience it offers. Use it as a design reference, extract the parameter contract into an explicit allow-list specification, and implement against a maintained library or a small in-house component we control.
How can I help you explore Laravel packages today?