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

Event Dispatcher Contracts Laravel Package

symfony/event-dispatcher-contracts

A small set of PHP interfaces that abstract Symfony's event dispatcher, letting you build on proven event semantics and swap implementations without locking your code to a specific package.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Architecture / vendor lock-in decision. This is an interfaces-only package — it ships abstractions (EventDispatcherInterface, Event, StoppableEventInterface), not runtime behavior. Adopting it is therefore a low-cost architectural commitment, not a feature investment: it costs one composer require and a code-style convention, and it buys optionality if we ever dispatch or consume events outside Laravel.
  • Shared library / SDK strategy. The clearest ROI case. If we maintain any package consumed by more than one application (a billing module, an audit-trail library, an internal SDK, a CLI worker), type-hinting against these contracts instead of Illuminate\Contracts\Events\Dispatcher keeps that package installable in Symfony, Lumen, or plain-PHP contexts. This is a one-way-door decision worth getting right early and cheap to get right now.
  • Roadmap sequencing for PSR-14. It lets us split the work into two very different bets: event definitions (cheap, near-zero risk, reversible) and dispatcher replacement (expensive, breaking, hard to reverse). A PM can fund phase one and defer phase two indefinitely — a useful way to capture most of the upside without the migration.
  • Build vs. buy. If a roadmap item calls for "our own event bus," this package is the honest answer to "don't invent the interface layer." Buy the contracts, build only the parts that are actually ours.
  • Migration / M&A / multi-framework positioning. Relevant if we are acquiring a Symfony-based codebase, selling a component to customers on mixed stacks, or planning to extract services that must exchange domain events.
  • Testability and observability. Framework-agnostic event value objects are easier to assert on, serialize for logging, and replay — modest but real support for DDD-style modular monolith design.

Leading indicator to watch: does anything in our portfolio actually run outside Laravel today? If no, this decision has no near-term payoff and should be parked, not scheduled.

When to Consider This Package

Adopt when:

  • We own at least one package or module with a plausible second-framework consumer, now or within two quarters.
  • A customer, partner, or acquired team requires PSR-14 compatibility.
  • We are extracting services and want domain events to survive a future dispatcher swap.
  • The team is already on PHP 8.1+ / Laravel 10+, so there is no upgrade tax.
  • We want a cheap convention change (new event classes extend the Symfony contract) with no dispatcher migration attached.

Look elsewhere — or do nothing — when:

  • It is a single Laravel application with no external consumers. Illuminate\Events is idiomatic, better documented, better tooled (Event::fake(), make:event), and already covers it.
  • The team would need a bridge (spatie/laravel-psr-event-dispatcher or a homegrown adapter) and has no bandwidth to own it. Dependents: 0 in this data is the warning light: there is essentially no Laravel-specific ecosystem around this package, so we would be the maintainer of last resort for any bridge we adopt.
  • Anyone proposes replacing Laravel's dispatcher outright. That is the high-risk phase and should be a separate, justified project — not a side effect of adopting contracts.
  • The events are trivial hooks in a small app; abstraction overhead exceeds the benefit.
  • Stakeholders are dependency-sensitive and will read "another package" as risk without seeing the interface-only distinction.

Gating questions before approval: Why PSR-14 — real cross-framework need or speculative elegance? Which dispatcher do we keep? How many existing listeners would need signature changes? Does anything depend on Event::fake()?

How to Pitch It (Stakeholders)

For executives — frame as insurance, not a feature. "This is a small, free, standards-based interface package backed by Symfony's API stability guarantee. It doesn't add functionality; it removes a future switching cost. Concretely: our domain events stop being Laravel-shaped, so if we add a Symfony service, acquire a team on a different stack, or ship a module to a customer with a mixed environment, that work doesn't require rewriting event logic. It's MIT-licensed, interfaces-only, and reversible in a single commit — the cost is a coding convention plus a short review, not a migration. I'm recommending we apply it to our shared library only, and explicitly not touch the dispatcher."

For engineering — frame as a two-phase decision with a clear stop line.

  • Phase 1 (approve now): New event classes in shared/portable modules extend Symfony\Contracts\EventDispatcher\Event. Laravel's own Event already extends the Symfony base, so this is compatible with the native dispatcher and changes nothing at runtime. Add a lint/CI rule so the convention holds.
  • Phase 2 (do not approve now): Swapping Laravel's dispatcher for a PSR-14 one. That requires a bridge, listener signature changes, and reworked test doubles — real cost, real breakage risk, no current driver.
  • Known limits to state up front: contracts provide no dispatcher, no listener provider, and no tooling; Laravel's dispatcher isn't PSR-14-compliant; PHP 8.1+ required; the Laravel-side ecosystem is thin, so any bridge is ours to own.
  • Success criteria for the pilot: the shared module installs and its tests pass in a non-Laravel harness, zero changes to existing listeners, and no measurable dispatch overhead.

Ask: a one-sprint pilot scoped to a single shared module, with a written decision to defer dispatcher migration until a concrete cross-framework consumer exists.

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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel