wyrihaximus/ticking-promise
A ReactPHP promise that fires a callback on a recurring interval, making it simple to schedule periodic tasks inside asynchronous PHP applications without manual event-loop timer wiring.
Architecture fit. wyrihaximus/ticking-promise is a single-purpose utility that turns an event-loop tick into a ReactPHP promise. It is not a Laravel package: no service provider, no config, no facade, no container binding. Fit is therefore determined entirely by whether the consuming application actually runs a react/event-loop. Laravel's default execution model is synchronous request/response (PHP-FPM) with asynchronous work pushed to queues via Horizon or SQS. Neither path exposes a shared loop. Laravel Octane is also a poor fit: its Swoole and RoadRunner drivers own their own runtimes and do not hand you a LoopInterface. The realistic homes for this package are sidecar daemons (websocket fanout, TCP workers, AMQP consumers via bunny), CLI tooling, and test harnesses for libraries that already speak promises. In those contexts it fills a genuine gap: yielding to the loop without allocating a timer, exposed as a thenable that composes with the rest of the promise chain.
Integration feasibility. Mechanically trivial. One composer require, no registration, no migration. The only meaningful contract is React\Promise\PromiseInterface, and the implementation surface is small enough to audit in a single sitting. There is no framework coupling to fight.
Technical risk. Low in absolute terms, moderate in ownership terms. The repository has 6 stars, 0 dependents, a single maintainer, and a very recent release date (2026-04-12), which signals active but narrow usage. Specific risks a TPM should track:
react/promise v2 and v3 differ in cancellation and unhandled-rejection reporting; the package's constraint needs checking against what the app already locks.Key questions before approval. Does the application run a ReactPHP loop anywhere in production? What are the php and react/promise constraints in the vendor composer.json, and do they satisfy every app in the estate? Is the use case production code or test support? Do we need cancellation semantics, and does the tick still fire after cancel? Who is the named owner?
Stack fit. Additive and non-invasive. The package has no Laravel coupling and does not touch the container, HTTP kernel, or queue worker lifecycle. It is a leaf dependency. Adopt it only where a loop already exists, and consider confining it to a require-dev test-support package if the only consumer is test code, which keeps production requirements clean.
Migration path. There is nothing to migrate. The realistic replacement scenario is swapping a hand-rolled new Promise(fn ($resolve) => Loop::futureTick($resolve)) into the package. When doing so, wrap it behind an internal interface (for example App\Support\Async\nextTick(): PromiseInterface) so application code depends on our seam rather than a 6-star vendor class. That keeps a fork or a swap to a two-line local implementation cheap and reversible.
Compatibility. Pin an exact version. Verify the composer.json constraints against the oldest PHP runtime in the estate and against whatever react/promise version is already resolved, using composer why-not in each app. Confirm that no Octane driver is expected to provide the loop. Nothing in Laravel's stack registers react/event-loop globally, so there is no conflict surface, only a missing-precondition surface.
Sequencing.
Maintenance. Code maintenance is effectively zero. Dependency maintenance is not: the vendor releases frequently, so Dependabot will generate recurring pulls. Set a policy by release type (patch auto-merge with green CI, minor manual, major scheduled) rather than reviewing each one. Document the fork path so the bus factor does not become an escalation.
Support. Community-only, GitHub issues on a low-traffic repository, no SLA. That is acceptable for a dependency of this size and blast radius, but it should be stated explicitly in the adoption record so nobody treats it as platform-grade infrastructure later.
Scaling. Runtime cost is negligible, one loop tick. The scaling consideration is architectural, not computational: horizontally scaling PHP-FPM workers does nothing for promise-based code because there is no shared loop across workers. If throughput depends on this package, the real lever is the daemon architecture around it, not the package.
Failure modes.
Mitigations: assert the loop is running at construction boundaries, attach rejection handlers where promises cross module seams, wrap call sites in a timeout so a hung tick surfaces as an error rather than a stall, and isolate the version constraint per app.
Ramp-up. Reading the source and tests takes about 15 minutes. Understanding ticks versus timers versus microtasks takes longer and is the actual onboarding cost. Budget one short internal note plus one reference test as the onboarding artifact. Do not classify this as "platform" until it has a named owner and a written precondition that a loop is present; absent that, treat it as a scoped utility with a documented build-your-own alternative.
How can I help you explore Laravel packages today?