innmind/event-bus
A lightweight event bus for PHP from the Innmind ecosystem. Publish domain events and register listeners or handlers to react to them, keeping producers and consumers decoupled behind a small, predictable API that fits neatly into larger Innmind applications.
What we are evaluating. innmind/event-bus is a small, framework-agnostic event dispatcher from the Innmind functional-PHP ecosystem (Baptiste Langlade). It is MIT licensed, has zero stars, zero dependents, and is archived. The supplied score of 0 with an opportunity score of 19.28 is consistent with a package that has failed an automated health gate: no adoption signal, no maintenance signal, no upstream support path.
Architecture fit. Poor for a Laravel application, for three structural reasons:
Illuminate\Events\Dispatcher, Illuminate\Contracts\Bus\Dispatcher) wired into the container, queues, broadcasting, model events, subscribers, and testing helpers (Event::fake()). Introducing a second bus means two registration mechanisms, two dispatch paths, and an ambiguous answer to "where does this listener live?" That is a durable source of production defects, not a stylistic preference.Sequence, Set, Maybe, Either) rather than Laravel's container-resolved, type-hinted listeners. Interop requires a hand-written adapter layer: mapping native events into Innmind value objects, resolving listeners from the Laravel container, and translating error states back into exceptions the framework's handler can see.The one defensible fit: a framework-agnostic domain layer inside a larger monorepo where every bounded context already uses Innmind conventions. That is not our codebase.
Technical risk.
| Risk | Severity | Why | Mitigation |
|---|---|---|---|
| Archived upstream | High | No PHP version constraint updates, no CVE response, no bug fixes | Vendor/fork, or do not adopt |
| Zero dependents | High | No field validation; unknown edge cases | Treat any behavior as unverified |
| Single maintainer, no successor | High | Bus factor of one, already realized | Fork ownership assigned to a named team |
| Non-idiomatic API | Medium | Ramp-up and adapter maintenance cost | Wrap behind an internal contract |
| PHP/framework compat drift | Medium | Archived packages fail silently on new PHP minors | Pin and test in CI, or avoid |
| MIT licensing | Low | Permissive; standard attribution | Legal sign-off is a formality |
Key questions to resolve before any further work.
composer why innmind/event-bus)Stack fit. Ranked against realistic alternatives for our Laravel services:
| Option | Fit | Maintenance | Verdict |
|---|---|---|---|
| Laravel native events + queue | Native | Framework-owned | Default choice |
| Symfony Messenger (standalone or via Laravel bridge) | Good | Active | Strong for async/transport-heavy needs |
| Ecotone | Good | Active | Viable if we want messaging + event sourcing patterns |
league/event |
Fair | Low activity | Only for tiny framework-agnostic libs |
innmind/event-bus |
Poor | Archived | Reference only |
Recommendation. Do not take a runtime dependency. Use the package as a design reference: it is a compact, readable example of a dispatcher contract, and reviewing its interface is a legitimate half-day exercise for an engineer designing our own port. Zero stars and an archived status mean there is no reputational or support cost to skipping it, and no community expectation to honor.
Migration path (if a team has already prototyped with it).
DomainEventBus interface owned by us (dispatch(object $event): void), with no Innmind types in the signature. Every call site depends on this, never on the package.ShouldQueue listeners for anything doing I/O.composer.json so composer audit and abandoned-package checks stay green.Compatibility. Verify PHP constraint satisfaction and PSR-4 autoloading on our target runtime. Because the package is archived, assume the declared constraints reflect PHP 8.0–8.1 era tooling; a composer update on a future PHP minor is a likely break. Any adoption must include a lockfile pin plus a CI job that installs from a clean cache.
Sequencing. Architecture decision record first (1 week), port definition second (1 week), pilot third (1 sprint), rollout per bounded context afterward. Do not sequence this ahead of any work that depends on the event contract being stable — the contract, not the library, is the deliverable.
Maintenance. Archived status transfers all maintenance to us. Realistically that means vendoring the source into the repo or forking it, which converts a "free" dependency into an owned asset with an assigned maintainer, a patch process, and a review obligation on every PHP upgrade. Budget roughly 2–5 engineer-days per year for a stable fork, materially more if we extend it. That is the true cost against which the "it's free and MIT" framing should be judged.
Support. No upstream issues, no CVE feed, no documentation beyond source, no community. Any incident is debugged from first principles by whoever is on call. For a payments-adjacent or customer-facing path this alone should disqualify it; for an internal tool it is survivable but still a tax.
Scaling. A pure in-process dispatcher scales only with the request lifecycle: fan-out cost is paid synchronously inside the user's request, so latency and failure blast radius both grow with listener count. Horizontal scaling of the app does nothing for listener throughput. Any real async requirement — retries, backpressure, isolation — must be built on top, at which point Laravel's queue-backed listeners or Symfony Messenger deliver more for less.
Failure modes to design against.
Ramp-up. The functional idioms (Sequence, Maybe/Either, immutability) are unfamiliar to most Laravel engineers. Expect 2–4 weeks before a mid-level developer is productive and, more importantly, expect review friction: the code will not look like the rest of the codebase, and reviewers cannot pattern-match against existing services. This is a recurring cost, not a one-time one.
Bottom line. This is a reference implementation, not a dependency. The event contract is worth owning; this package is not. Recommend closing the evaluation with a "no-adopt, reference-only" decision recorded in the ADR, and redirecting the effort toward the internal DomainEventBus port plus Laravel's native dispatcher.
How can I help you explore Laravel packages today?