league/tactician-command-events
Adds command events to League Tactician, dispatching events around command handling so you can hook into the command lifecycle with listeners instead of cluttering handlers. A lightweight integration for PHP apps using Tactician.
Architecture fit. The package addresses a real CQRS/domain-event concern: recording events on a command during handling and releasing them only after the command completes successfully. That pattern fits a command-bus architecture and maps conceptually to Laravel’s DB::afterCommit() plus domain events. The concrete fit is weak, however: it is a Tactician middleware plugin, and Laravel applications do not use Tactician’s bus pipeline by default. Leverage is therefore limited to teams already operating a Tactician command bus, or willing to adopt one alongside Laravel’s native bus.
Integration feasibility. Low for a modern Laravel codebase. The last release was 2015-12-31, with 14 stars and zero dependents. Composer constraints are likely PHP 5.6-era and pinned to old league/tactician / league/event versions, which will conflict with Laravel 9–12 and PHP 8.x. There is no Laravel service provider, configuration, facade, or documented Laravel bridge. The package is MIT-licensed, so forking or vendoring is legally straightforward, but it is not a drop-in integration.
Technical risk. High. Key risks are abandonment, PHP 8 incompatibility, transitive dependency conflicts, undocumented event ordering and transaction semantics, and no evidence of modern test coverage. The package also creates a second eventing mechanism beside Laravel’s dispatcher, which increases cognitive load and makes debugging dispatch order harder. The low package score (0.49) and opportunity score (23.92) reinforce that this is not a strategically valuable dependency.
Key questions.
Stack fit. Poor for greenfield Laravel. Good only as a narrow adapter inside an existing Tactician-based application. Laravel’s native command bus, event dispatcher, queued listeners, and afterCommit hooks cover the same use case with first-party support.
Migration path. Two viable paths:
RecordsEvents interface/trait on commands, a middleware that collects and clears events after handling, and an adapter that forwards them to Laravel’s EventDispatcher.The second path is usually preferable: it removes the dependency, makes transaction semantics explicit, and keeps ownership internal.
Compatibility. Verify PHP 8.1+ compatibility, Tactician 1.x/2.x compatibility, and league/event version constraints. Laravel’s dispatcher is not a drop-in PSR-14 implementation in all versions, so a small adapter may be required. If the app uses database transactions, event release must be coupled to commit, not just handler return.
Sequencing.
Maintenance. Upstream maintenance is effectively zero; the adopter owns the code. The surface area is small, so a vendored middleware is manageable, but Composer resolution and PHP upgrades become recurring toil. Budget for periodic compatibility patches rather than expecting upstream releases.
Support. No meaningful community support: 14 stars, zero dependents, and no releases since 2015. There will be no security advisories or timely fixes. Internal ownership, documentation, and tests are mandatory before production use.
Scaling. The middleware itself is stateless and cheap. The real scaling concern is synchronous event release: listeners performing I/O will inflate command latency. Queue listeners where possible, and be explicit about whether events are dispatched inside or outside the transaction. Throughput will be bounded by listener work, not by the middleware.
Failure modes.
Ramp-up. Low for engineers already familiar with Tactician; moderate for Laravel-only teams who must learn a second bus, middleware pipeline, and event lifecycle. The conceptual overhead is disproportionate to the package’s size.
TPM recommendation. Do not adopt as a new production dependency. If the pattern is required, port the small middleware into the application, bind it to Laravel’s dispatcher and transaction lifecycle, and treat the original package as reference material only.
How can I help you explore Laravel packages today?