liam-wiltshire/laravel-jit-loader
Laravel JIT Loader adds just-in-time relationship loading to Eloquent, helping eliminate N+1 queries without manually eager-loading every relation with with(). It loads relationships only when needed, keeping model access simple and query-efficient.
Architecture fit. The package is a narrow, single-purpose Eloquent extension: a trait that hooks model hydration and issues eager-loads for relationships declared in a $jit property. Architecturally it sits at the ORM layer, which is the highest-leverage but also highest-blast-radius place to intervene in a Laravel application. It fits cleanly into conventional Laravel codebases (controllers → repositories → Eloquent models) and is orthogonal to existing with() usage, so it does not force a refactor of query-building code. It is not a fit for teams running heavy custom query builders, non-Eloquent data access, or read/write-split setups where implicit extra queries create unpredictable routing.
Integration feasibility. Integration cost is genuinely low: one use statement and one property per model. The stated compatibility with explicit with() and preventLazyLoading() reduces the political cost of adoption, since it doesn't conflict with existing Laravel idioms. The primary feasibility blocker is not effort but staleness: last release November 2020, which predates Laravel 9/10/11 and the PHP 8.x baseline most teams now run. Before any commitment, a TPM must confirm the trait's hook points still exist and behave identically on the target Laravel version — this is a spike, not an assumption.
Technical risk.
$jit property," which raises the cost of incident triage for engineers unfamiliar with the model.cursor(), and hydration of large collections needs verification; per-model eager-loading on a 100k-row chunk is a materially different cost profile than on a 20-row request.Key questions.
preventLazyLoading(), API Resource serialization (whenLoaded), and pagination?Stack fit. Good fit for a standard Laravel monolith or modular monolith on Eloquent, particularly one with a mature preventLazyLoading() discipline in non-production and a real N+1 problem in production logs. Poor fit for Laravel Octane? — actually compatible in principle, but worth verifying the trait holds no static state across requests. Poor fit where the data layer is deliberately abstracted (CQRS-style read models, API-backed repositories), since the value proposition evaporates once you leave Eloquent.
Migration path. Treat this as an opt-in pilot, not a platform standard:
with() is already present.Compatibility. Verify against the actual pinned versions rather than the composer.json constraints, which are stale by definition. Confirm PHP 8.1+ compatibility, Eloquent hydration hook stability, and coexistence with static analysis (Larastan will not infer that $jit relations are loaded, so type-safety and IDE completion degrade — @property docblocks on models become necessary).
Sequencing. Adopt after the team has established explicit with() conventions and lazy-loading prevention, not instead of them. This package is an optimization layer on top of a disciplined baseline; introducing it as a substitute for query discipline produces opaque models. Pair adoption with an ADR recording the accepted over-fetch trade-off.
Maintenance. The dominant cost. Expect to fork within 12 months if the application tracks current Laravel releases. Budget a named owner and a documented patch cadence; this is a ~200-line trait and cheap to maintain, but only if someone is assigned. Add a dependency-review checkpoint so a future framework upgrade doesn't silently break eager-loading.
Support. Internal support burden is low in volume but high in discoverability: on-call engineers will not know a model preloads relations unless the convention is documented. Mitigate with a short internal runbook and a lint/review rule that any model adding $jit must state the justification and the endpoint(s) it serves.
Scaling. The main scaling concern is over-fetch on high-volume batch paths — exports, scheduled jobs, queue workers. Every model with a broad $jit multiplies per-row query cost across large collections. Enforce a policy that $jit is limited to relations used by the dominant read path, and explicitly test batch workloads. Read replicas and connection routing should be unaffected, but extra queries will consume replica capacity.
Failure modes.
with() in the call stack.with() and $jit overlap, depending on hook implementation.Ramp-up. Low for a mid-level Laravel engineer (trait + property is minutes). The real ramp-up is organizational: teaching reviewers to treat $jit as a performance decision requiring evidence, and teaching on-call engineers to check model properties before profiling. Estimate one sprint to pilot, one to standardize, with the primary gate being measured query-count improvement — not developer enthusiasm. Given the staleness and the modest opportunity score, my recommendation is a scoped pilot on proven N+1 hotspots with a fork-ready posture, not a framework-wide convention.
How can I help you explore Laravel packages today?