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

Laravel Local Class Scope Laravel Package

mpyw/laravel-local-class-scope

A tiny Laravel macro that lets you reuse global scope classes as local query scopes. Call User::scoped(ActiveScope::class) or pass constructor arguments, chain scopes, and optionally wrap them in model methods or traits. Includes a PHPStan extension for static analysis.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is a single auto-discovered macro that adds scoped() to Eloquent query builders, accepting either a Illuminate\Contracts\Database\Eloquent\Scope class-string, an instance, or a class-string plus constructor arguments. It introduces no new contract, service provider to publish, config, or migration — the only abstraction engineers must learn is Laravel's existing Scope interface. Architecturally this is the lightest possible shape for the capability: it reuses the same Scope classes already used for global scopes, so there is no parallel scope dialect to maintain. It aligns with laravel/ideas#636, meaning the idiom is directionally consistent with where the framework has publicly discussed going.

Integration feasibility. High. composer require plus auto-discovery gets a working macro in one minute. The real work is codebase-side: inventorying existing app/Scopes/ classes and duplicated predicates, then refactoring call sites. There is a bundled PHPStan extension for scoped() typing, which is the difference between adopting this safely and adopting it with suppressions; the ordering constraint (this package's extension.neon before Larastan's) is a concrete, testable setup step, not a vague caveat.

Technical risk. The dominant risk is provenance, not code. 23 stars, zero dependents, a single maintainer, and at least one release (v2.2.0) that is a version bump with no functional content. The dataset's 2026-06-13 release timestamp is future-dated and must be verified against the repository before any planning assumption rests on it — the difference between "stable by design" and "under-invested" changes the recommendation. Secondary risks are technical and enumerable:

  • Macro name collision. A global scoped() macro is a shared namespace; another package today or a future Laravel method of the same name produces an ambiguous-call upgrade hazard.
  • Global-scope semantics applied locally. Scope classes written for one-time global application can call remove() on other scopes, assume single invocation, or depend on booted() timing. Applied locally and repeatedly, they can behave surprisingly.
  • Version ceiling. Hard requirement on PHP ^8.2 and Laravel ^11–14. On Laravel ≤10 this is a blocker, not a trade-off. It also means the package must keep pace with Laravel majors — a single maintainer is the constraint on that.

Key questions. Who owns the macro internally if upstream goes quiet, and is vendoring under MIT acceptable to procurement/security? Does any current or planned dependency register scoped() on the builder? Are our candidate global scopes idempotent and free of remove()/boot-timing assumptions when applied locally? Does the PHPStan extension ordering actually work in our phpstan.neon without suppressions? What is our Laravel upgrade cadence relative to the maintainer's release cadence?

Integration Approach

Stack fit. This is a first-filter decision: Laravel 11–14 with PHP 8.2+. Teams on Laravel ≤10 should defer outright. Teams on the supported matrix and already using class-based Scope objects are the natural fit; teams with only closure scopes or dynamic request-driven filters will get less value and should not pilot.

Migration path. There is no data or schema migration — this is a code refactor with a cheap reversal. Extract a duplicated predicate into App\Scopes\XScope implementing Scope, replace inline clauses with Model::scoped(XScope::class) or the parameterized form, and keep the diff reviewable. The fallback path is removing the package and inlining or wrapping the call sites, so the decision is reversible at any point. Avoid a repo-wide sweep: backfill only where a predicate is duplicated three or more times, because a sweep maximizes the surface to unwind later.

Compatibility. Three concrete compatibility surfaces: (1) the scoped macro name against other packages and future framework methods; (2) PHPStan/Larastan extension ordering; (3) the package's Laravel version constraint against your upgrade cadence. The native-Laravel migration story is favorable — if the ideas proposal lands, moving to the framework equivalent should be mechanical — which lowers the cost of adopting now and the cost of being wrong.

Sequencing.

  1. Verify the macro is live with a throwaway scope on the target Laravel version.
  2. Inventory app/Scopes/ and booted()/addGlobalScope() registrations; audit candidates for local-use safety (remove(), single-invocation assumptions, boot timing).
  3. Enable the PHPStan extension ahead of Larastan and confirm no new suppressions.
  4. Pilot in one non-critical domain with real duplication.
  5. Gate on measurable duplication removed, no test regressions, no analysis suppressions, and engineers preferring it to closures after a sprint.
  6. Standardize or stop. If fewer than roughly five scopes are shared across two or more models, treat it as a style preference and decline.

Operational Impact

Maintenance. Low ongoing code maintenance — the package is a small, forkable MIT macro with a narrow surface, and it can be vendored internally if upstream stalls. The maintenance burden is instead organizational: pinning a version, watching upstream releases against Laravel majors, and owning the scoped idiom internally (naming, app/Scopes/ conventions, argument-passing style, chaining and precedence documentation). A single-maintainer, zero-dependent package means the bus factor is effectively one, and that should be written down as an accepted risk rather than discovered later.

Support. No commercial support. Issues are handled by the maintainer on a best-effort basis. Teams with vendor-support or procurement policies requiring adoption evidence will fail this package on 23 stars and zero dependents — that is a legitimate outcome, not an objection to be argued past. Internal support means nominating an owner for the macro and the scope conventions.

Scaling. Runtime cost is negligible: the macro delegates to the same builder the scope would have modified. The scaling risk is behavioral, not performance — every additional predicate silently changes query plans and index usage, and caching layers keyed on query shape will see different shapes. Parameterized scopes can also be misused to build filters dynamically from request payloads, which reintroduces the abstraction cost the package was meant to remove.

Failure modes.

  • Macro collision on scoped() → ambiguous call or hard failure on upgrade.
  • Non-idempotent or remove()-calling scope applied locally → unexpected scope removal or duplicated predicates.
  • PHPStan extension loaded after Larastan → analysis gaps or new suppressions, defeating the main quality argument.
  • Laravel major upgrade outrunning the package → version pin blocks the framework upgrade, or the macro breaks at runtime.
  • Maintainer abandonment → no security patches; mitigated only by the small vendorable surface.
  • Unaudited global scope reused locally → behavior that differs from its global application in ways tests do not cover.

Ramp-up. Minimal for any engineer already familiar with Scope. The three call styles (Class::class, new Scope(...), Class::class, ...args) are learnable from the README in minutes, and the PHPStan extension makes IDE-level discovery work. The genuine ramp-up cost is team convention: where scopes live, whether they take constructor arguments, whether to expose scopeX() wrappers or traits, and how chaining and precedence are documented. Budget a sprint for the pilot to surface that, and treat engineer preference for the idiom over closures as an explicit success criterion rather than an assumed one.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings