laraditz/action
A Laravel package for single-action classes that keep your app DRY. Each action handles one business operation, takes input via its constructor, resolves dependencies automatically through Laravel's container, and supports queueing.
run() entry point, a data() helper, and a make:action Artisan generator. For a mid-level Laravel engineer, replicating this internally is roughly a day of work plus a test. That makes "buy" a very low-stakes commitment but also a weak one — the decision to consider is borrow the idea, own the code versus take the dependency and inherit its maintenance posture.ShouldQueue + dispatch()) and method injection into handle() mean the same operation can run synchronously from a controller and asynchronously from a worker without two implementations. This directly supports roadmap items like "run this operation in the background," "expose this via API and console," or "retry failed operations," and it is the clearest product justification for the pattern.Consider it when:
composer.json verified directly rather than inferred from the README.DB::transaction(), logging, events) and comfortable forking or inlining it if upstream goes quiet.Look elsewhere (or build internally) when:
One flagged design risk to resolve before adoption: the data() helper returns all constructor properties as an array, which makes Model::create($this->data()) extremely convenient — and a silent over-posting hazard. Adding a property later (e.g. userId, isAdmin) changes what gets persisted without touching the handle() body. If you adopt, mandate explicit payload arrays or tightly scoped $fillable in review, and treat this as a standing code-review rule rather than a footnote.
For executives: This is a small, MIT-licensed utility that gives the team a consistent home for business logic — one class per operation, callable identically from a web request, a background job, or a command. The business payoff is fewer bloated controllers, logic that is written once and reused across entry points, and workflows that are easier to test and therefore safer to change. The catch is credibility of the dependency: it has essentially zero community adoption and a single maintainer, so it should be positioned as an internal convention we are borrowing, not a strategic platform bet. Recommendation: approve a short, time-boxed pilot on one high-value workflow with an explicit success metric, and pre-approve the fallback of absorbing the ~one-file abstraction internally. Cost of exit is negligible; cost of over-committing is a stalled refactor.
For engineering: The package supplies an abstract Action base class, a static/instance run() that resolves handle() through the container (so services are injected automatically, sync and in queue workers alike), a data() helper, and a make:action generator writing to app/Actions. Queue support comes from implementing ShouldQueue with the standard Queueable/InteractsWithQueue/SerializesModels traits — do not add Dispatchable, the base class already provides dispatch() and the trait will conflict. Treat the following as our own responsibility, not the package's: input validation, authorization, transactions, events, and idempotency, all of which matter more once actions are invoked from non-HTTP contexts. Two guardrails for review — never feed data() straight into create() without pinning $fillable, and pin the version with a committed lockfile since a 2.0-style revamp already happened once at near-zero adoption. Start with one genuinely complex workflow; if the abstraction doesn't pay for itself there, it won't pay for itself anywhere.
How can I help you explore Laravel packages today?