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 Hooks Laravel Package

alizharb/laravel-hooks

Laravel Hooks provides a simple action/filter system for Laravel apps, letting you register and run hooks to extend packages and application code without modifying the original source. Ideal for modular, maintainable customizations.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Assessment scope: AlizHarb/laravel-hooks v1.2.0 (upgrade from v1.1.0 baseline; no prior internal assessment exists, so this establishes the initial position). Release is versioned as a minor bump but self-described as a "major update" — treat semver signalling as unreliable and pin explicitly.

Verdict: Conditional adopt. Strong fit for decoupled UI/commerce extensibility; do not enable Dynamic Eloquent Extensions in core domain models during the first cycle.

Architecture fit — Good, with a caveat on scope creep

  • The package is an action/filter hook bus — a well-understood Laravel pattern (WordPress-style) that maps cleanly onto our existing event/listener and Blade component usage. Low conceptual debt.
  • v1.2.0's Dynamic Eloquent Extensions (#[DynamicRelation], #[DynamicCast], #[DynamicScope], Hook::model(User::class), HasDynamicHooks) shift the package from decoration to runtime model mutation. This is architecturally invasive: model behaviour would no longer be fully derivable from source. Acceptable for plugin/module ecosystems; risky for a system of record.
  • Hook Circuit Breaker is the most valuable addition for us — it converts a class of cascading-failure outages into contained, degraded experiences. This alone justifies evaluation.
  • Type-safe DTO support (class/interface hints with automatic validation) materially improves contract discipline between hook emitters and listeners; this is the feature I'd standardise on internally.

Integration feasibility — High

  • Composer-installable, Laravel package auto-discovery; no infrastructure, queue, or database dependency implied.
  • Zero-config laravel-modular discovery is neutral-to-positive: it costs us nothing if we don't run that ecosystem, and it means the maintainer's roadmap is oriented toward multi-module/plugin architectures rather than single-app convenience.
  • CI signals are verified: Pest on PHP 8.3/8.4, PHPStan Level 5, Pint. Level 5 is a floor, not a guarantee — magic-method-heavy code (HasDynamicHooks) is precisely what static analysis struggles to prove safe.
  • Blade @hook('name', 'fallback.view') is a clean, low-risk entry point; adoptable in a single sprint with no schema or API surface change.

Technical risk — Moderate overall; High if dynamic extensions are used on core models

Risk Severity Notes
Runtime model mutation obscures behaviour High #[DynamicRelation]/#[DynamicScope] make relations non-discoverable via static reading; onboarding and debugging cost rises.
Circuit breaker masks silent failures High Automatic silencing is a resilience win and an observability liability — a muted listener returns "success" with no effect. Must be paired with telemetry/alerting before enabling in production paths.
Metadata caching across deploys Medium "Refined caching logic for dynamic model metadata" is unverifiable from release notes; stale caches after deploy are a classic failure mode for discovery-based engines.
Long-running process state (Octane/Swoole/queue workers) Medium Per-request dynamic extension of models raises state-leak questions. Unconfirmed in notes — blocking question.
Bus factor / maintenance continuity Medium–High Single-maintainer OSS repo; enterprise-critical paths depending on it need a fork or vendoring contingency.
Semver discipline Low–Medium "Major update" shipped as 1.2.0. Pin exact versions; do not float ^1.2.
Static analysis / IDE ergonomics Low–Medium Dynamic methods and attributes degrade autocomplete and PHPStan coverage at the call site; team-level discipline required.

Key questions to raise with the maintainer (blocking before Phase 2)

  1. Explicit supported Laravel/PHP matrix, and whether Laravel 12 and Octane are in CI or best-effort.
  2. Are dynamic model extensions request-scoped or container-singleton? What is the reset/teardown contract in long-running workers?
  3. Circuit breaker semantics: default threshold, half-open recovery behaviour, and what event/telemetry is emitted on open/silence.
  4. Is there a config switch to make silencing fail-loud in non-production, and to globally disable dynamic model extensions?
  5. Does the discovery/metadata cache invalidate on deploy, or is a manual warm step required?
  6. Security posture for attribute-based extension: can a listener registered by third-party code add a relation or scope to a model with authorization implications (mass-assignment, query-scope bypass)?
  7. Upgrade/back-compat guarantees for v1.x, and deprecation policy.

Integration Approach

Stack fit — Strong for the hook bus, conditional for model extension

  • Fits our Laravel monolith and any future modular split; the action/filter bus is a natural seam for plugin or tenant-specific behaviour and for Blade-level UI slots.
  • @hook(..., 'fallback.view') maps directly onto our existing concern of "optional widget renders nothing / renders broken". Adopt early — lowest risk, immediate UX benefit.
  • DTO-typed hook signatures give us an enforceable contract between emitters and listeners, which is the single biggest long-term maintainability lever in this package.

Migration path — Incremental, four phases, each independently reversible

  1. Phase 0 – Containment (½ sprint). Pin 1.2.0 exactly in composer.json. Add to the dependency register with an owner and a fork contingency note. No production usage.
  2. Phase 1 – Read-only hooks (1 sprint). Use hooks for non-authoritative concerns only: admin notices, Blade slots, notification fan-out. Enable Blade fallbacks everywhere. Ship circuit breaker disabled (observe-only) while baseline telemetry is built.
  3. Phase 2 – DTO contracts + circuit breaker on (1–2 sprints). Standardise hook payloads as typed DTOs with validation. Enable the circuit breaker on third-party/flaky listeners only; wire open/silence events into existing alerting so a muted listener pages someone rather than disappearing.
  4. Phase 3 – Dynamic extensions, gated (evaluation only). Restrict Hook::model() / #[DynamicRelation] to a single non-critical, low-traffic model. Require a written internal ADR and code-owner review for any addition to core domain models. Re-evaluate at the next major.

Compatibility considerations

  • laravel-modular, laravel-themer, filament-modular-luncher, modular-js are ecosystem companions we do not currently run. Confirm they are optional (no transitive hard dependency) before install; if they are pulled in, re-run the dependency review.
  • No database migrations, config publishing, or queue topology changes implied — clean rollback: remove the hook registrations, remove the package. Dynamic extensions are the exception: once model behaviour is runtime-injected, removal is a code change, not a config change. That asymmetry is the core reason for the Phase 3 gate.

Sequencing rationale Value is front-loaded in the low-risk features (Blade fallbacks, DTOs, circuit breaker) and back-loaded in the high-risk one (dynamic model extensions). Ship in that order so the team builds operational muscle — and a telemetry baseline — before touching anything that reshapes Eloquent.

Operational Impact

Maintenance

  • Small, single-maintainer upstream. Budget a nominal recurring cost for version tracking, plus a decision point now on whether to vendor/fork at adoption or only on abandonment. For a package landing on mission-critical request paths, I recommend vendoring at Phase 2.
  • Pin exact versions and review every release note manually — the v1.1.0→v1.2.0 "minor" bump contains invasive capability. Do not automate minor upgrades.
  • Internal ownership: one named code owner for hook registrations and the model-extension allowlist; otherwise hook sprawl becomes unowned surface area.

Support

  • Community-only upstream support; no SLA. Escalation path is our fork.
  • Two internal support obligations must be documented before Phase 2: (a) how to diagnose a silenced hook, (b) how to enumerate what a given model has been extended with at runtime. Without (b), incident response on extended models is materially slower.

Scaling

  • Hook dispatch is in-process and synchronous — cost scales with listener count per hook on hot paths. Treat high-traffic hooks as a budgeted resource and measure; require a Pulse/Debugbar snapshot in any PR adding listeners to request-critical paths (the release's improved Pulse/Debugbar instrumentation makes this cheap, which is a genuine plus).
  • Discovery/metadata caching should keep the registration cost off the request path, but this is unverified — benchmark before scaling listener counts.
  • Octane/worker compatibility is the open scaling question (see Technical Evaluation); assume it must be validated, not assumed.

Failure modes and mitigations

Failure mode Impact Mitigation
Circuit breaker silences a listener silently Business logic skipped with no error — worst-case "silent wrong answer" Alert on open/silence events; fail-loud in staging; periodic reconciliation checks
Third-party listener throws in request path 5xx on critical paths Circuit breaker + async/queued listeners for non-blocking work
Stale dynamic-model metadata after deploy Missing relations/attributes → runtime errors Explicit cache-warm/clear step in deploy runbook; verify on first post-deploy smoke test
Dynamic scope shadows a security-relevant query constraint Data exposure Ban dynamic extensions on models with authorization scopes; code-owner review gate
Type-hinted DTO mismatch on listener signature Hook dispatch errors at runtime, not build time Contract tests per hook; register hooks in boot with smoke assertions
Upstream abandonment or breaking 1.x change Rework on critical paths Exact pin + vendored fork at Phase 2
Octane/queue state bleed across requests Cross-tenant leakage — severe Block Phase 3 until proven request-scoped with a test

Ramp-up

  • Conceptually light for anyone who has used Laravel events or WordPress hooks: ~1 day to productivity on Phases 1–2 features.
  • Dynamic Eloquent Extensions are the real learning cost: ~1 week plus a written internal convention doc, because the difficulty is not the API but reading a codebase where model behaviour lives elsewhere. Enforce two rules from day one: (1) every hook registration names its owner and intent in a comment, (2) no dynamic model extension without an ADR.
  • Onboarding debt is permanent, not transient: every future engineer pays the "where does this behaviour come from?" tax. That cost is justified for a plugin platform and hard to justify for a conventional application — which is the single question this evaluation should put to the architecture review board.

Recommendation: Approve Phases 0–2 now (bounded, reversible, clear value). Hold Phase 3 pending answers to the state-scoping, cache-invalidation, and circuit-breaker-observability questions, and re-assess at v1.3 or the next genuinely breaking release.

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.
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
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route