keepsuit/laravel-temporal
Laravel Temporal integrates the Temporal PHP SDK with Laravel, making it easy to define and register workflows and activities, configure task queues and workers, and run durable background workflows using familiar Laravel configuration and Artisan commands.
composer require keepsuit/laravel-temporal — the service provider and facade are auto-discovered. You also need a reachable Temporal server; for local work run the Temporal CLI dev server (temporal server start-dev) rather than standing up a cluster.php artisan vendor:publish --tag=temporal-config → config/temporal.php. The knobs that matter on day one are address (usually from TEMPORAL_ADDRESS, default 127.0.0.1:7233), namespace, the default task queue, and the TLS/mTLS block for Temporal Cloud.TemporalWorkflow / TemporalActivity contracts (they define the shape of everything you'll write), the Temporal facade / workflow-client surface (how you start work), and TemporalFaker (how you'll iterate 90% of the time).execute() method that calls two activities — one that hits an external API via your existing HTTP client, one that sends a notification. Start it from a controller with Temporal::newWorkflow(OrderWorkflow::class, $orderId)->start(), and run a worker to execute it. That exercises the full loop: dispatch → queue → activity container resolution → result.execute() free of I/O: it should only sequence activity calls, timers, child workflows, and signal/query handling. Every DB query, HTTP call, mail send, and file operation belongs in an activity class.->workflowId("order-{$orderId}") makes a retried dispatch (queue redelivery, user double-click, webhook replay) collapse into the existing run instead of spawning a duplicate. Combine with ->workflowExecutionTimeout() / ->taskQueue() as needed.Temporal::fake() in feature tests, assert assertWorkflowStarted, and unit-test activities directly with normal Laravel test doubles since they're plain container-resolved classes. Reserve running against the real dev server + a worker for a small set of integration tests, because that's slow.spatie/laravel-data. In 2.3.1 and earlier, workflow execution crashes when the Spatie data package isn't installed, because the data-converter path assumes it. If you do use Spatie DTOs, the fix is a no-op — but keep the version constraint loose enough that you don't get stuck on a broken 2.3.1 pin in a lock file.now(), Carbon::now(), rand(), env(), config(), Str::uuid(), or Model::find() inside a workflow — replay re-executes the method and any non-deterministic value desyncs history. Use the SDK's workflow clock (Workflow::now()) and move everything else into activities.spatie/laravel-data, remember that the worker must be able to deserialize the same class — deploying a changed DTO while old runs are queued will blow up on hydration.php artisan config:cache in deploy means TEMPORAL_ADDRESS changes require a re-cache; a worker pointing at localhost in production fails with a connection error that looks like a code bug.startToCloseTimeout deliberately rather than relying on defaults.->taskQueue(...) or timeout chain on every dispatch, that's the signal to build a small factory/helper around the facade.How can I help you explore Laravel packages today?