laravarc / eventer
Transport-agnostic domain event dispatch and consumption for Laravel — broker-agnostic SEND/RECEIVE with EventContract wire envelopes.
v1.0.0
2026-09-05 16:59 UTC
Requires
- php: ^8.2
- illuminate/bus: ^10.0|^11.0|^12.0|^13.0
- illuminate/console: ^10.0|^11.0|^12.0|^13.0
- illuminate/contracts: ^10.0|^11.0|^12.0|^13.0
- illuminate/events: ^10.0|^11.0|^12.0|^13.0
- illuminate/filesystem: ^10.0|^11.0|^12.0|^13.0
- illuminate/pipeline: ^10.0|^11.0|^12.0|^13.0
- illuminate/queue: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
- nesbot/carbon: ^2.0|^3.0
Requires (Dev)
- larastan/larastan: ^3.10
- laravel/pint: ^1.29
- orchestra/testbench: ^9.0|^10.0
- pestphp/pest: ^3.0|^4.0
- php-amqplib/php-amqplib: ^3.7
Suggests
- ext-pcntl: Recommended for graceful consumer shutdown in laravarc:eventer consume (SIGTERM/SIGINT).
- ext-rdkafka: Required for the built-in Kafka transporter (alias: kafka).
- illuminate/http: Required for the built-in Webhook transporter (alias: webhook).
- illuminate/redis: Required for the legacy Redis transporter (alias: redis) — will be split into redis-pubsub and redis-stream in a future release.
- laravarc/core: Required when registering EventerExtension with Laravarc Core generation hooks.
- laravarc/eventer-mqtt: Roadmap — transporter alias mqtt (MQTT). Not yet implemented.
- laravarc/eventer-redis-pubsub: Roadmap — transporter alias redis-pubsub (Redis Pub/Sub). Not yet implemented.
- laravarc/eventer-redis-stream: Roadmap — transporter alias redis-stream (Redis Streams). Not yet implemented.
- laravarc/eventer-sqs: Roadmap — transporter alias sqs (Amazon SQS). Not yet implemented.
- php-amqplib/php-amqplib: Required for the built-in RabbitMQ transporter (alias: rabbitmq).
Provides
None
Conflicts
None
Replaces
None
README
Transport-agnostic domain event dispatch and consumption for Laravel.
Usable with or without laravarc/core.
Design Principles
- Broker agnostic — the same domain event can be sent or received through Laravel, RabbitMQ, Kafka, Redis, webhooks, or custom transporters.
- Framework friendly — integrates with Laravel's event dispatcher, queue, pipeline, and service container.
- Language agnostic — wire envelopes use stable
eventName+version, not PHP class names. - Contract first —
EventContractdefines the public API between producers and consumers. - Eventer orchestrates events, not brokers — transporters are pluggable adapters; Eventer owns routing, contracts, and orchestration.
Install
composer require laravarc/eventer php artisan vendor:publish --tag=eventer-config php artisan laravarc:eventer cache
Quick start
use Laravarc\Eventer\Contracts\EventContract; use Laravarc\Eventer\Facades\Eventer; final class UserDeleted implements EventContract { public function __construct(public int $userId) {} public static function eventName(): string { return 'user.deleted'; } public static function version(): int { return 1; } } Eventer::dispatch(new UserDeleted(42)); Eventer::channel('external')->dispatch(new UserDeleted(42)); Eventer::internal()->dispatch(new UserDeleted(42)); Eventer::via('laravel')->dispatchNoFallback(new UserDeleted(42));
Commands
| Command | Alias | Purpose |
|---|---|---|
laravarc:eventer cache |
larc:eventer cache |
Build event name → class index (PSR-4 scan only; see scan_* config) |
laravarc:eventer cache --clear |
same | Clear cached index |
laravarc:eventer manifest |
larc:eventer manifest |
Output JSON contract manifest |
laravarc:eventer consume {transporter} |
larc:eventer consume |
Consume inbound events from a Receivable transporter |
laravarc:eventer make-transport {Name} |
larc:eventer make-transport |
Scaffold a custom transporter |
Event index scan config
laravarc:eventer cache never iterates the Composer classmap (that would load arbitrary vendor classes and can fatal). Configure discovery in config/eventer.php:
| Key | Purpose |
|---|---|
scan_paths |
Project roots whose composer.json PSR-4 maps are read |
scan_namespaces |
Extra namespaces to include (e.g. packages under vendor/) |
exclude_namespaces |
Namespace prefixes to skip |
exclude_classes / include_classes |
Per-class deny/allow lists |
Eventer vs Laravel Event
Eventer facade |
Laravel Event facade |
|
|---|---|---|
| Purpose | Domain-event transport (channels, transporters, fallback) | In-process listener bus |
| Typical use | Eventer::dispatch($event) |
Listeners, Event::fake() |
Use Eventer when you care how/where a domain event is delivered. Use Laravel Event for classic in-process listener registration.
Documentation
| Topic | Guide |
|---|---|
| Installation & setup | docs/01-installation.md |
| Defining events (EventContract) | docs/02-defining-events.md |
| Dispatching events | docs/03-dispatching.md |
| Channels & routing | docs/04-channels.md |
| Transporters & config | docs/05-transporters.md |
| Consuming events | docs/06-consuming.md |
| Wire format (envelope) | docs/07-wire-format.md |
| Artisan commands | docs/08-commands.md |
| Configuration reference | docs/09-configuration.md |
| Testing | docs/10-testing.md |
License
MIT — see LICENSE.