windwalker/event
Lightweight event dispatching for PHP and the Windwalker framework: register listeners, dispatch events, and decouple components with a simple, PSR-14-friendly API.
Architecture fit. windwalker/event is a standalone, framework-agnostic event dispatcher extracted from the Windwalker ecosystem. It provides the classic dispatcher surface — listen/addListener, priority-ordered listeners, deferred/queued listener execution, and (depending on version) PSR-14 compatibility. Architecturally it is a peer of Illuminate\Events\Dispatcher and symfony/event-dispatcher, not a complement to them. For a Laravel codebase, this is a duplicate capability, not a gap-filler: Laravel already ships events, listeners, subscribers, wildcard listeners, queued listeners, and event discovery out of the box. The realistic integration pattern is "wrap it behind our own interface and use it only where we deliberately want to be framework-independent," which is a hard sell versus simply depending on psr/event-dispatcher and Laravel's adapter.
Integration feasibility. Composer-installable and low-ceremony. The friction is not installation but coexistence: two dispatchers in one container means two listener registries, two ordering semantics, two exception policies, and a confusing mental model for the team. Bridging is possible (register Windwalker listeners from a Laravel service provider, or delegate Illuminate events into it), but every bridge is glue code we own forever. The absence of first-party Laravel integration packages, service providers, or facade support means the integration cost is entirely ours.
Technical risk. High, concentrated in provenance rather than code. The repository carries the [READ ONLY] marker and 0 stars / 0 dependents, which strongly suggests it is a subtree split or archived mirror of a monorepo package (Windwalker's own framework), not an independently stewarded library. That has three consequences: releases may be driven by monorepo tags rather than semantic intent for this package; issue triage may happen upstream, not here; and abandonment risk is real even though the MIT license guarantees we can fork. The code itself is small and legible, so a fork-and-own path is viable — but that converts a dependency decision into a maintenance commitment, which needs an explicit owner.
Key questions.
psr/event-dispatcher ^1.0?Illuminate\Events plus psr/event-dispatcher adapters does not?Stack fit. Poor for a Laravel application; neutral for a framework-agnostic PHP library. The opportunity: 40.03 and Score: 0 signals point the same direction: this is a commodity dispatcher in a category Laravel already owns. Recommendation is do not adopt as a primary dispatcher. The only defensible use cases are (a) a genuinely framework-agnostic domain package that must not depend on illuminate/*, or (b) a Windwalker-origin application being ported into our estate.
Migration path. For a Laravel target, do not migrate to this package — migrate through an interface. Define our own thin EventDispatcher port (or adopt psr/event-dispatcher directly), bind Laravel's dispatcher as the default implementation, and treat any third-party dispatcher as an interchangeable adapter behind that port. If we are coming from a Windwalker application, the translation is mechanical: listener registration maps 1:1, priority ordering maps to Laravel's listener priority, and deferred listeners map to Laravel's ShouldQueue listeners — but the semantics of "deferred" (in-process post-dispatch vs. queue-backed) are not equivalent and must be reconciled explicitly.
Compatibility. Low framework coupling makes it broadly installable, but that same neutrality means zero Laravel ergonomics: no Event::listen facade, no ShouldQueue, no subscriber discovery, no Event::fake() test helper. Our test suite leans heavily on Event::fake() and assertDispatched; adopting a second dispatcher fragments those assertions and forces bespoke fakes.
Sequencing. (1) Spike: verify version, PSR-14 conformance, and release cadence; confirm subtree-split status. (2) Interface-first: land the dispatcher port and bind Laravel's implementation. (3) Only if a concrete framework-agnostic requirement surfaces, evaluate Windwalker behind that port with a throwaway adapter and a documented exit path. Do not sequence this ahead of any Laravel-native event work; there is no dependency forcing function.
Maintenance. This is the dominant cost driver. Zero dependents and a read-only mirror mean we are effectively alone with bugs. Budget for owning a fork if we adopt: pinned fork, internal test suite, and a named maintainer. Under MIT we can fork, but "can fork" is a contingency, not a strategy. If we adopt without a fork owner, expect silent drift and stale dependencies.
Support. No commercial backing, no vendor SLA, no security advisory channel specific to this package. We would be subscribing to upstream monorepo advisories and hoping this file set is in scope. Contrast with symfony/event-dispatcher and illuminate/events, both of which have security release processes we already consume.
Scaling. In-process dispatch only. Deferred listeners appear to execute synchronously after the dispatch cycle rather than via a queue, so there is no horizontal offload — heavy listener work blocks the request. Under Laravel Octane or long-running workers, listener registries accumulate if listeners are registered per-request; that is a real memory-growth failure mode we would have to police. For high-throughput async fan-out, this package is the wrong tool regardless of framework.
Failure modes. (1) Listener exceptions — verify whether dispatch aborts on first throw or isolates failures; either behavior is defensible but must be known. (2) Priority inversions when listeners register from multiple service providers. (3) Duplicate registration under octane/worker reuse. (4) Silent no-ops — a typo'd event name simply dispatches to nobody, with no discovery or compile-time check. (5) Two-dispatcher confusion, where a developer registers on the wrong instance and the handler never fires — the single highest-probability operational bug in a hybrid setup.
Ramp-up. The API is small and any mid-level PHP developer is productive in an hour. The real ramp-up cost is organizational: teaching the team when to use which dispatcher, and writing down the rule before someone violates it. That documentation burden, plus fork ownership, is disproportionate to the value delivered. Net assessment: reject for Laravel-native work; retain only as a documented, adapter-wrapped option if a hard framework-agnostic constraint emerges, and only with an assigned fork owner.
How can I help you explore Laravel packages today?