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

Eloquent Builder Decorator Laravel Package

paulhenri-l/eloquent-builder-decorator

A Laravel package for decorating Eloquent query builders. Wrap builders to add reusable query logic, filters, and composable behavior without touching your models. Keeps query customization clean and testable.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • Eloquent's Illuminate\Database\Eloquent\Builder is the primary query surface in virtually every Laravel application. This package targets that surface with a decorator/wrapper pattern: a class holds a builder instance and proxies __call/fluent methods through to it, returning the decorator so custom, named query methods can be chained with full type fidelity.
  • Laravel already offers several overlapping mechanisms: local scopes (public function scopeActive(...)), Builder::macro(), and a first-class custom builder via Model::newEloquentBuilder() / Model::newQuery(). The decorator is a fourth path. Its unique value is IDE-friendly, statically analyzable, type-safe fluent methods without mutating the model or global Builder state — a real gap versus macros and scopes.
  • Fit is therefore narrow but legitimate: it is only compelling in codebases that want reusable, composable, typed query objects (repository/query-object style) and are willing to wrap the builder per call site. It does not change how Eloquent resolves relations, scopes, or hydration, so it lives beside, not inside, the ORM's core lifecycle.

Integration feasibility

  • Installation is trivial (Composer, single dependency) and the concept is small — likely a base class plus magic forwarding. There is no service provider, no config, and no schema impact, so trial cost is low.
  • The practical blocker is version drift: released April 2020, this targets the Laravel 6/7 and PHP 7.x era. PHP 8.x (especially 8.1+ deprecations around magic methods, #[ReturnTypeWillChange], and static-return types) and Laravel 8→11 changes to ForwardsCalls, Conditionable, and builder internals make compatibility a verification task, not an assumption.
  • Because the decorator must forward a large and evolving Builder API surface, it is inherently fragile against upstream additions — every Laravel minor release can add builder methods whose return semantics the wrapper may not model correctly.

Technical risk

  • Abandonment risk (high): Last release 2020, 11 stars, 0 dependents, no community. Effectively unmaintained; assume you own the code the moment you adopt it.
  • Ecosystem validation (very low): Zero dependents and an aggregate score of ~0.085 mean no production signal. Treat it as an untested reference implementation rather than a vetted library.
  • Decorative leakage (medium–high): Eloquent internals and relation methods (whereHas, with, relationship builders, paginate, chunk, cursor, find) return concrete Builder/Relation/LengthAwarePaginator instances. A wrapper cannot intercept all of these, so chains will silently "unwrap" back to the raw builder, defeating the type promise and producing confusing errors.
  • Static analysis (medium): __call-proxied methods are often invisible to Larastan/PHPStan and IDE autocomplete unless the decorator uses @mixin or explicit stubs; the package's typing story needs validation.
  • Type-hint friction (medium): Application code, policies, observers, and scopes that type-hint Builder will reject the decorator, forcing either Builder-returning escape hatches or pervasive signature changes.

Key questions

  • Which Laravel and PHP versions are supported, and does it run cleanly on the current LTS target (PHP 8.1+, Laravel 10/11) with no deprecations?
  • How does it handle methods that return the underlying builder, relations, or paginators — does chaining preserve the decorator, and is that documented?
  • Is forwarding implemented via ForwardsCalls/__call, and is it @mixin-annotated for PHPStan/IDE support?
  • Does it support static entry points (Model::query() replacement) and per-model registration, or is it caller-constructs-only?
  • What is the actual LOC and test coverage? At this size, is a 100–200 line internal base class cheaper than adopting an abandoned dependency?
  • Has anyone verified behavior with eager loading, whereHas closures, chunkById, and pagination?

Integration Approach

Stack fit

  • Fits any standard Laravel monolith or modular app using Eloquent; no infra, queue, or front-end implications. Value is concentrated in teams that already favor query objects or repositories and want chaining ergonomics.
  • Poor fit where teams rely on local scopes and macros as the house style, or where static analysis is strict — the decorator adds a parallel abstraction that must be taught and policed.

Migration path

  • Adopt incrementally per model/domain: wrap at the call site (UserQuery::make(User::query()) or an equivalent factory) rather than globally replacing newQuery(). This keeps the blast radius to opted-in read paths and leaves writes, relations, and existing scopes untouched.
  • Do not attempt to subclass or globally swap the Eloquent builder; that maximizes breakage and makes rollback expensive.

Compatibility

  • Gate adoption on a spike against the current framework/PHP matrix, including a deprecation-free run and PHPStan/Larastan analysis of the proxy surface.
  • If incompatible, the package is small enough to fork and patch, or to reimplement internally with a thin, documented ForwardsCalls-based decorator plus @mixin annotations and tests pinning the builder methods actually used.

Sequencing

  1. Spike (1–2 days): Install in a branch; validate PHP/Laravel compatibility, chaining fidelity through where/orderBy/paginate, and static analysis.
  2. Decision gate: Compare against local scopes, macros, and a custom newEloquentBuilder() subclass on the same three or four real queries. Pick the lowest-abstraction option that meets the typing goal.
  3. Fork or vendor (if adopting): Pin a fork, add tests around the forwarded methods you depend on, and document the supported API subset.
  4. Pilot: One domain, read-only query paths, with a code-review rule requiring the decorator to stay on the chain.
  5. Broaden: Extend per model only after the pilot shows no unwrapping or type-hint surprises.

Operational Impact

Maintenance

  • Full ownership burden: no upstream activity since 2020, so bug fixes, PHP/Laravel upgrades, and security triage land on your team. Budget a standing maintenance line item, or prefer an internal ~150-line implementation you control outright.
  • Low code volume keeps the cost bounded, but the forwarded surface grows with every Laravel release, so maintenance is recurring rather than one-off.

Support

  • No vendor, no maintainer responsiveness, no issue history to lean on. Internal documentation and tests become the only support artifacts.
  • Team onboarding must cover the decorator's boundaries — specifically that some methods return raw builders — or engineers will misread type errors as bugs.

Scaling

  • Runtime overhead is negligible: magic-method proxying costs microseconds per call and is dwarfed by query and hydration time. No effect on horizontal scaling or throughput.
  • Cognitive scaling is the constraint: as more models get decorators, the "which builder am I holding" question multiplies, and consistency depends on discipline and lint rules.

Failure modes

  • Silent unwrapping: relation methods, paginators, and chunk/cursor return concrete types, so chains lose the decorator and later custom methods fail or fall through to BadMethodCallException.
  • Version breakage: a Laravel upgrade changes builder internals or adds methods the proxy mishandles, surfacing as runtime errors in production query paths.
  • Type-hint rejection: passing a decorator where Illuminate\Database\Eloquent\Builder is expected throws TypeError.
  • Static analysis blind spots: proxied methods flagged as undefined, eroding trust and prompting @phpstan-ignore noise.
  • Divergent query styles: coexisting scopes, macros, and decorators produce inconsistent, hard-to-review data-access code.

Ramp-up

  • Conceptually low: the decorator pattern and fluent proxies are familiar to mid/senior Laravel engineers, roughly half a day to productive use.
  • Real ramp-up cost is in the guardrails — writing the internal conventions, examples, and lint/static-analysis rules that prevent unwrapping and style drift — which is a week-scale investment for the team, not the individual.

TPM recommendation

  • Treat as a reference pattern, not a dependency. At 11 stars, zero dependents, and a 2020 release, the supply-chain and maintenance risk outweighs the ergonomic gain. Reimplement the pattern internally (or start with local scopes/macros and escalate only if typing pain is demonstrated), and gate any adoption on a compatibility spike plus a documented supported-method subset.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core