Product Decisions This Supports
- Framework-Agnostic Architecture: Adopting this package enables the team to design event-driven systems that can seamlessly integrate with Symfony, Laravel, or other PSR-14-compliant frameworks, reducing long-term technical debt and vendor lock-in. This is critical for projects targeting multi-framework ecosystems (e.g., shared libraries, microservices, or CLI tools).
- Modular Design: Supports a build vs. buy decision by allowing the team to leverage standardized contracts for event dispatching, avoiding reinventing the wheel while maintaining flexibility. Ideal for greenfield projects or refactoring monolithic event systems into decoupled components.
- Interoperability Roadmap: Aligns with a strategic roadmap to adopt PSR standards (e.g., PSR-14, PSR-15) for better tooling compatibility (e.g., testing frameworks, observability tools). Enables future-proofing for projects where event-driven architecture is a core pillar.
- Domain-Driven Design (DDD): Facilitates the creation of domain events that are reusable across layers (e.g., API, CLI, background jobs) without coupling to Laravel’s event system. Useful for projects using DDD patterns like Event Sourcing or CQRS.
- Testing and Observability: Standardized event contracts simplify mocking and testing event listeners, improving developer productivity and reducing flakiness in integration tests. Also aids in observability by ensuring consistent event structures (e.g., for logging or monitoring tools).
When to Consider This Package
-
Adopt When:
- Your project requires cross-framework compatibility (e.g., shared libraries used in Laravel and Symfony).
- You’re building a modular monolith or microservices where event contracts must remain stable across services.
- You prioritize PSR compliance for tooling interoperability (e.g., with PHPUnit, Pest, or Symfony’s Messenger).
- Your team is investing in long-term maintainability and wants to avoid framework-specific event quirks.
- You’re designing domain events that need to be testable or serializable (e.g., for event sourcing).
-
Look Elsewhere When:
- You’re building a pure Laravel application with no plans for multi-framework reuse—Laravel’s native event system is simpler and more idiomatic.
- Your project lacks PHP 8.1+ support, as this package enforces modern PHP features.
- You need real-time event dispatching (e.g., WebSockets, reactive programming), where Laravel’s
Event system or dedicated libraries (e.g., react/event-loop) may be better suited.
- Your team lacks bandwidth to maintain a PSR-14 bridge for Laravel (e.g.,
laravel-psr-event-dispatcher), as integration isn’t plug-and-play.
- Events are trivial (e.g., simple notifications) and don’t justify the abstraction overhead.
How to Pitch It (Stakeholders)
For Executives:
"This package lets us build event-driven systems that work across multiple frameworks—like Laravel and Symfony—without getting locked into one. It’s like using a universal adapter for power outlets: we can plug our events into any compatible system, saving time and reducing risk. For example, if we later decide to spin out a shared library for our microservices, the events will already be framework-agnostic. The tradeoff is a slight upfront complexity, but the long-term flexibility and tooling compatibility (e.g., better testing, observability) make it a strategic investment."
For Engineering Teams:
*"By adopting PSR-14 contracts for events, we can:
- Decouple event definitions from Laravel’s dispatcher, making them reusable in CLI tools, APIs, or other frameworks.
- Future-proof our architecture—if we ever migrate parts of the system to Symfony or another framework, the events will ‘just work’.
- Improve testability—standardized event structures simplify mocking and debugging.
- Leverage existing tooling—packages like
symfony/event-dispatcher or league/event can drop in for advanced use cases.
Downside: We’ll need to either:
- Use a bridge like
laravel-psr-event-dispatcher to connect Laravel’s dispatcher to PSR-14, or
- Refactor existing event listeners to work with the contracts (though Laravel’s
Event class already extends Symfony’s Event, so minimal changes may be needed).
Recommendation: Start with domain events where cross-framework reuse is valuable (e.g., UserRegistered, OrderProcessed), and gradually expand the pattern. Avoid over-engineering for simple use cases."*
For Developers:
*"This package gives us standardized event interfaces so our events can work anywhere. Here’s how to use it:
- Extend
Symfony\Contracts\EventDispatcher\Event for your event classes (e.g., class UserRegistered extends Event).
- Laravel’s
event() helper will work with these, but you can also use Symfony’s dispatcher if needed.
- For Laravel integration, type-hint
Symfony\Contracts\EventDispatcher\Event in your EventServiceProvider to enforce the pattern.
Pro tip: Define public const NAME = 'event.name' in your events for consistency. If you hit snags, check for PSR-14 bridges like laravel-psr-event-dispatcher."*