bnnvara/event-catalog
A Laravel package that provides a catalog for your application's events, letting you register, organize, and look up domain and broadcast events in one place. Useful for documenting event flows, wiring listeners, and keeping event-driven code discoverable and consistent.
Architecture fit. The first and most important finding is a stack mismatch. The package is described as a Symfony bundle, while the consuming platform is Laravel. Symfony bundles are not a portable packaging format: a bundle's value is delivered through Bundle subclasses, Extension/Configuration classes, compiler passes, services.yaml wiring, and tag-based autoconfiguration. Laravel's service container does not load any of that. A Laravel application can consume the classes inside a bundle — and Laravel already runs on Symfony components — but it cannot consume the bundle's integration surface. Any adoption therefore implies either (a) an adapter/service-provider wrapper we write and own, or (b) lifting the domain logic out of the bundle and discarding the framework glue. Both are re-platforming work, not dependency adoption.
What the package likely is. "Catalog events" in a Symfony context most plausibly means a domain-event catalog: a registry of named events, their payload shapes, and versions, used to publish/dispatch domain events consistently across services. That is genuinely valuable in an event-driven architecture — it is the artifact that makes contracts explicit and versioning governable. The architectural fit is therefore strong conceptually and weak mechanically. We should evaluate it as a reference implementation and contract model, not as a drop-in library.
Integration feasibility. Low to moderate, gated on unknowns. Feasibility hinges on where the boundary sits: if the catalog is a pure-PHP registry with framework glue only at the edges, extraction is a day or two of work. If the catalog's persistence, dispatching, or subscriber resolution is bound to Symfony Messenger, Doctrine, or the Symfony EventDispatcher, extraction becomes a rewrite of the integration layer and may not be worth it. Because the repository is on Bitbucket with no visible CI, badges, or distribution metadata, we also cannot confirm it is installable via Composer from Packagist at all — it may require a VCS repository entry and credentials.
Technical risk. High, and concentrated in provenance rather than code quality. Zero stars, zero dependents, and a score of 0 are weak signals individually — internal packages routinely look like this — but combined with a single-vendor Bitbucket origin they indicate a package with no external consumers, no community review, and no demonstrated install path. Specific risks: unknown license (a blocker for redistribution or reuse outside the originating organization), unknown PHP and Symfony version constraints (may pin us to an EOL runtime), unknown test coverage, no security disclosure process, and an effective bus factor of the originating team.
Key questions.
EventCatalog usable standalone, or does it require the Symfony container, Messenger, or Doctrine?Stack fit. Do not attempt to install the bundle into a Laravel application and expect it to behave. The correct framing is: the concept fits our stack well (Laravel has a first-class event dispatcher and queue system, and an event catalog would strengthen contract discipline across our services), but the package does not. Plan for an adapter or an extraction, budgeted as internal development rather than as a dependency.
Migration path. Two viable routes, decided by the key questions above.
EventCatalogServiceProvider that binds the catalog's core classes as singletons, registers any custom dispatcher bridging to Laravel's Event facade, and publishes config. This is the lowest-effort path and preserves upstream updates, but it permanently ties us to a third-party's internal release cadence and to Symfony-shaped internals.DependencyInjection and bundle scaffolding, retain the catalog model and any schema artifacts, and republish internally under our own namespace. Higher upfront cost, but it converts an unmaintained external dependency into an owned asset with our tests, our license header, and our versioning. For a package with zero dependents, this is usually the right call.Recommendation: prototype the adapter route for one sprint purely to read the code and quantify the coupling, then default to extraction unless the coupling turns out to be trivial.
Compatibility. Verify before any code is written: supported PHP range against our runtime, Symfony component versions against what Laravel already ships, and whether the package requires extensions or services we do not run. Check for global state, static registries, and service-locator patterns — these are common in bundles and are exactly what breaks under Laravel's container lifecycle and under Octane's long-lived workers.
Sequencing.
Maintenance. Assume we own this from day one. The upstream is a single organization's Bitbucket repository with no visible external contribution flow; issues and pull requests may go unanswered, and the project may be archived without notice. Budget ongoing ownership: dependency bumps, PHP version upgrades, and schema evolution. If we take the adapter route, every upstream release is a potential break we must absorb; if we extract, the cost is front-loaded and then predictable.
Support. There is no community, no documentation site, no Stack Overflow footprint, and no security advisory channel. Internal knowledge will reside with whoever performed the integration. Mitigate with a written runbook, an ADR capturing why we adopted it, and a named secondary owner. For a package that governs event contracts, undocumented behaviour is a compounding liability — the catalog is supposed to be the source of truth, so gaps in its own semantics are unusually damaging.
Scaling. Catalog operations are typically configuration-time or startup-time: registering event names, resolving schemas, validating payloads. That scales trivially. The risks appear if the catalog is consulted per-event on a hot path — for example, validating every payload against a schema at dispatch time — which adds latency and CPU to every publish. Under Octane or a queue worker, also watch for registries that accumulate state across requests, and for listener registration that grows unbounded if the catalog is rebuilt per job. Load-test the dispatch path specifically, not just the application.
Failure modes. The most dangerous failure is silent schema drift: the catalog declares a payload shape, a producer ships something else, and nothing validates it, so consumers break at a distance and after a delay. Others worth designing against: container or boot failure from unresolved Symfony-style service definitions (fails loudly, at least); missing or duplicated event handlers when bridging two dispatchers; version skew between services pinning different catalog versions, producing disagreement about what an event means; and, on the extraction route, divergence from upstream such that we can no longer take their fixes. Instrument the catalog itself — emit a metric when an event is published that is not registered, and alert on it.
Ramp-up. Non-trivial and asymmetric. The team needs enough Symfony bundle literacy to read compiler passes and extension configuration, which is a real skill gap for engineers who work exclusively in Laravel, and that knowledge has no other application in our stack. Expect one to two weeks for a senior engineer to reach comfortable fluency, plus review capacity from someone who has shipped a Symfony bundle before. Weigh this against the alternative: an internally built Laravel-native catalog would use skills the team already has, and the ramp-up cost alone may exceed the cost of building it. That comparison should be explicit in the adoption decision rather than assumed away.
How can I help you explore Laravel packages today?