maksimru/eloquent-subquery-magic
Architecture fit
The package is a thin, trait-based extension to Eloquent’s query builder. It adds subquery helpers (select subqueries, where subqueries, ordering by subquery) that can be attached to existing models without altering schema, service providers, or the application’s domain layer. Architecturally this is a low-ceremony fit: it sits alongside Eloquent macros and local scopes rather than competing with them, and it introduces no new persistence abstraction. For teams already comfortable composing raw SQL fragments inside Eloquent, the mental model is familiar.
Integration feasibility
Technically trivial to install — a composer require, a trait on the target models, and no migrations or configuration. The real feasibility question is version compatibility. The last release was October 2019, which places it in the Laravel 5.5–5.8 / PHP 7.x window. Its composer.json constraints almost certainly conflict with Laravel 8+, and likely with PHP 8.x. That means adoption on a current stack requires a fork with loosened constraints and a verification pass against the modern query grammar, or a composer constraint override that we would then have to own indefinitely.
Technical risk
selectSub, fromSub, closure-based whereIn/whereExists, and withCount/withSum/withAvg/withMax (8.x). The package’s differentiator has largely been commoditized, which weakens the case for taking on an unmaintained dependency.Illuminate\Database\Query\Builder/Grammar internals. Those internals are not covered by Laravel’s backward-compatibility promise, so a minor framework upgrade can break it at runtime rather than at install time.Key questions
selectSub/whereExists/withCount instead?Stack fit
Best suited to a legacy Laravel 5.x application, or a codebase already carrying similar low-level SQL helpers. Poor fit for a greenfield build on Laravel 9/10/11, where first-party subquery support removes the need entirely. Database-wise it is nominally driver-agnostic, but any output must be validated separately on MySQL, PostgreSQL, and SQLite if the test suite runs on SQLite while production runs on MySQL — dialect differences in correlated subqueries are a common source of test-only passes.
Migration path
Adopt in one of two modes. Preferred: skip the package and codify the equivalent patterns as local scopes on our models, using selectSub, whereExists, and withCount. This eliminates the dependency and gives us the same ergonomics. Fallback: fork the repository into our own namespace, loosen the version constraints, and pin the fork in composer.json with an explicit repositories entry so updates are deliberate rather than accidental.
Compatibility
Treat this as a pinned, owned dependency. Add it to the dependency register with an owner, a review date, and a note that upstream is dormant. Add a contract test that exercises every subquery shape we use, so a framework upgrade surfaces breakage in CI rather than in production.
Sequencing
Maintenance
The maintenance burden is not zero — it is transferred. Once forked, we own bug fixes, Laravel-version compatibility patches, and security review of the SQL construction path. Volume of work is small, but it recurs at every framework upgrade and sits on the critical path of that upgrade.
Support
No vendor, no active maintainers, no issue triage, no security advisories, and documentation limited to a README. Internal support means an internal runbook and a designated owner. Realistically, an engineer who leaves without documenting the fork becomes a single point of failure.
Scaling
Watch the query plans, not the package. Correlated subqueries execute per row and can turn a fast list endpoint into a table scan as data volume grows. Establish a habit of EXPLAIN-ing any query the package generates, ensure the correlation columns carry indexes, and set a review threshold: if a list endpoint exceeds a defined p95, the subquery becomes a join or a maintained counter column. Also consider read-replica routing — subqueries embedded in select clauses can make it harder to reason about which connection a statement lands on when models use separate read/write connections.
Failure modes
Ramp-up
Minimal. Any developer fluent in SQL and Eloquent can use the trait within an hour; the genuine ramp-up cost is teaching the team when not to use it, since the syntax makes the wrong (correlated) choice as easy as the right one. Budget roughly one to two engineering days for the spike plus ownership setup, and treat that as the full cost of deciding — the decision itself is likely to be "use first-party Eloquent instead."
How can I help you explore Laravel packages today?