Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

React Child Process Promise Laravel Package

wyrihaximus/react-child-process-promise

Promise-based wrapper around ReactPHP's child process component. Spawn child processes and handle their stdout, stderr, exit codes, and streams through promises, making asynchronous command execution simpler in ReactPHP applications.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — narrow and mismatched by default. This is not a Laravel package; it is a thin promise adapter over react/child-process in the ReactPHP ecosystem. Laravel's HTTP kernel and queue worker are synchronous, blocking execution models, while ReactPHP assumes a long-lived event loop owning the process. The only defensible fit is inside a queued job or artisan command that needs to fan out several external processes concurrently (media transcoding, PDF generation, git/CLI orchestration, bulk exports). Even there, the promise layer adds ergonomics, not capability — react/child-process already does the work.

Integration feasibility — trivial to install, non-trivial to operate correctly. composer require is a one-liner, but the real integration cost is loop lifecycle management: obtaining a LoopInterface, running it to completion, and guaranteeing it does not collide with any other ReactPHP loop in the same worker. ReactPHP permits only one running loop per process, so nesting this inside an existing daemon (e.g., a ReactPHP-based service) requires the caller to hand in the loop rather than create one.

Technical risk — elevated, driven by staleness rather than code quality. Last release 2020-12-04, 12 stars, 0 dependents. The code surface is small enough to audit in an afternoon, but zero dependents means effectively zero field validation. Primary concrete risks:

  • Dependency drift. A 2020 release is likely pinned to react/promise ^2.x. react/promise v3 shipped in 2023 and is required by newer ReactPHP components, so this package may block upgrades elsewhere in the tree. Must be verified against actual composer.json constraints before any commitment.
  • PHP 8.3/8.4 untested. The package declares a PHP range from the PHP 7 era; no CI evidence of modern runtime coverage.
  • Abandonment. Single-maintainer, no releases in ~4+ years. Treat as unmaintained.
  • Zombie/orphan processes. If the loop is terminated mid-flight (Horizon job timeout, SIGKILL, uncaught exception), child processes are not guaranteed reaped.
  • Pipe deadlock. Failure to drain stdout/stderr buffers while a process runs will hang the worker — a classic and hard-to-diagnose failure.

Key questions for the maintainer/team:

  1. Does the resolved dependency set coexist with the ReactPHP versions already in the tree, or with react/promise ^3?
  2. Does the promise resolve with the Process instance (streaming access) or with buffered output only? Exit code and stderr surfacing matter for error handling.
  3. Is there cancellation/timeout support, and does cancellation kill the child or merely detach the promise?
  4. Windows compatibility and shell-escaping behavior — is the command passed as an array or a string?

Integration Approach

Stack fit — prefer native Laravel first. Laravel 10+ ships Illuminate\Process (Symfony Process wrapper) with Process::pool() for bounded concurrent execution, and Laravel 11+ adds the Concurrency facade for forked parallel closures. Between those two, the overwhelming majority of "run N subprocesses in parallel from a job" use cases are covered without adding an event-loop dependency to a synchronous framework. The honest default recommendation is: do not adopt this package; adopt Process::pool().

Migration path — isolate behind a port if adopted anyway. If a specific gap justifies ReactPHP (incremental streaming of per-process output, dynamic fan-out where new processes are launched as earlier ones emit data, or an existing ReactPHP daemon in the stack), wrap the dependency:

  • Define an application-owned interface, e.g. App\Contracts\ProcessRunner, with a narrow method surface (run(array $command, ?int $timeout): ProcessResult).
  • Provide a SymfonyProcessRunner (default) and a ReactChildProcessRunner (opt-in) implementation.
  • Bind via the service container; keep the ReactPHP implementation out of HTTP request paths entirely.

This keeps the stale dependency behind a seam and makes removal a one-line container change.

Compatibility — pin aggressively. Lock exact versions of react/child-process, react/promise, and react/event-loop; add a CI matrix job on the PHP versions actually deployed; run composer why-not react/promise ^3 to surface conflicts early. Do not allow this package to constrain the upgrade path of the rest of the ReactPHP tree.

Sequencing:

  1. Measure. Profile the job. Confirm subprocess wall-clock time is the actual bottleneck and that serial execution is the constraint — not I/O, DB, or queue throughput.
  2. Prototype on native tooling. Implement with Process::pool() and a concurrency cap. Benchmark.
  3. Gate. Only proceed to ReactPHP if the prototype demonstrably fails on a named requirement (streaming semantics, dynamic fan-out).
  4. Wrap and vendor. Implement behind the interface; consider forking the ~small source into app/Support/ under MIT attribution rather than depending on Packagist.
  5. Instrument and ship behind a flag.

Operational Impact

Maintenance — you will own it. With no release since 2020 and a single maintainer, plan for fork-and-vendor. The upside: the source is small enough that internal ownership is a realistic one-time cost rather than a standing liability. Budget a named owner and a quarterly dependency-drift review.

Support — community-only, low responsiveness. No commercial backing, no SLA, and with 12 stars the pool of people who have debugged this in production is effectively empty. Internal runbooks and a documented failure playbook are prerequisites, not nice-to-haves.

Scaling — concurrency is unbounded unless you bound it. Every child process is a fork with its own memory, CPU, and file-descriptor footprint. On queue workers this compounds fast: N workers × M concurrent children. Enforce an explicit concurrency semaphore, per-process timeouts, and memory ceilings. Note the observability gap — Horizon and Telescope will not see child processes, so subprocess duration, exit codes, and failure rates need dedicated logging/metrics or you are flying blind.

Failure modes to design against:

  • Swallowed rejections. An unhandled promise rejection silently discards the error; every promise must terminate in an explicit then/catch (or done) with logging.
  • Zombie/orphan processes. Worker killed by Horizon timeout or OOM leaves children running. Mitigate with proc_open-level timeouts, a reaper, and cgroup/container-level isolation so orphans die with the worker.
  • Buffer deadlock. Non-drained stdout/stderr pipes stall the child and hang the worker until timeout.
  • Loop starvation / nesting. Starting a loop inside an already-running loop throws; a long-running child without yielding starves timers.
  • Unchecked exit codes. Treating "process exited" as success is the most common silent-data-corruption bug in this class of integration.

Ramp-up — a genuine but bounded cost. A Laravel team must internalize ReactPHP's mental model: promises, the single-loop constraint, non-blocking stream handling, and the difference between "the promise resolved" and "the process succeeded." Call it one to two engineer-days for a senior developer to be productive, plus ongoing cognitive overhead for anyone who later reads the job. Weigh that against Process::pool(), which requires zero new concepts.

Bottom line: the 0.35 score is a fair reflection. Technically sound as a small piece of glue, but stale, unvalidated, and functionally superseded by first-party Laravel tooling for the most common use case. Recommend native Process::pool()/Concurrency as the default, with this package (or a vendored fork of it) reserved for a demonstrable streaming/dynamic-fan-out requirement inside an existing ReactPHP daemon.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib