illuminate/remote
Illuminate Remote brings SSH-based remote command execution to Laravel, offering a fluent API for connecting to servers, running commands, and handling output inside your application. It fits Laravel’s ecosystem for deployment, server automation, and remote task workflows.
Architecture fit. The first thing to establish is that illuminate/remote is not a package you adopt — it is a read-only subtree split of laravel/framework. The repository exists for Composer discoverability and dependency resolution, not for direct consumption. Treat this evaluation as "should we use the framework's Remote component," and treat any composer require illuminate/remote as an anti-pattern that invites version skew against the framework.
The component is a fit when the application runtime itself needs to drive SSH — deployment hooks triggered from a control panel, per-tenant server provisioning, fleet-wide command fan-out from an admin UI, or replacing ad-hoc Symfony\Process calls that shell out to ssh. It is a poor fit for anything that belongs in CI or infrastructure-as-code: static deploys, repeatable provisioning, config drift remediation. Envoy, Deployer, Ansible, or a managed platform (Forge/Cloud) are the correct tools there, and choosing this component for those jobs means re-implementing orchestration semantics — idempotency, rollback, inventory — that mature tools already provide.
Integration feasibility. High, in the narrow sense that there is no new dependency to add. If the target framework version ships the component, Illuminate\Remote is already autoloadable. The real work is not integration but governance: deciding where remote execution is permitted to live in the codebase and what wraps it.
Technical risk. Moderate and concentrated in three areas. First, API stability: this is a young component with no independent semantic versioning — its surface moves with framework minors, and the split repo carries no changelog of its own. Second, knowledge risk: 18 stars is a proxy for the absence of a community corpus. There will be no Stack Overflow answers, no third-party tutorials, no blog posts describing failure modes. Every operational lesson is one we learn ourselves. Third, security surface: in-process SSH means credentials, host keys, and remote command strings live inside the application's memory, logs, and exception traces. That is a materially different threat model than a deploy tool running on a bastion.
Key questions for engineering.
Stack fit. Requires a modern PHP runtime (8.2+) on a Laravel 11/12-era framework. It composes naturally with the framework's config, credential, and queue primitives, which is the main argument for it over phpseclib — you inherit the framework's configuration and testing conventions instead of building a parallel stack.
Dependency hygiene. Do not add this to composer.json. If a pin is unavoidable (e.g., a security scanner demands explicit declaration), pin to the exact framework version and document why. Any drift between the split package and the framework is a class-not-found or signature-mismatch incident waiting for a Friday afternoon.
Migration path. Three common origins:
ssh2_* or phpseclib — wrap the new component behind the existing internal interface so call sites do not change. This is the lowest-risk migration and should be the default pattern regardless of origin.Symfony\Process + ssh — same wrapper approach; the win is structured output and error handling rather than string parsing.Compatibility checks. Confirm the split tag aligns with the framework tag in use, verify no conflict with an older illuminate/support in the dependency graph, and grep for any existing direct SSH usage that would now have two competing abstractions.
Sequencing. (1) Confirm component availability on the current framework version. (2) Spike against a single non-production host with a throwaway key. (3) Introduce an internal RemoteExecutor interface — this is the decision that makes the rest reversible. (4) Migrate one low-criticality job. (5) Only after a full upgrade cycle passes without breakage, move production-critical paths.
Maintenance. Package-level maintenance is zero — it is a build artifact of the framework. Wrapper-level maintenance is not. Budget explicitly for reviewing framework release notes on every upgrade, because that is the only changelog this component has. The read-only repo means no issue tracker, so defects are reported upstream against the framework or not at all.
Support. Effectively self-support. There is no community to escalate to, no vendor SLA beyond "upgrade the framework," and no external documentation to point new engineers at. Internal runbooks and a short design note are mandatory deliverables, not nice-to-haves — they are the entire knowledge base.
Scaling. SSH connections are stateful and blocking. Concurrency scales with worker count, not with request volume, so remote execution belongs on queue workers with explicit timeouts and concurrency caps. Within a single job, reuse one connection rather than reconnecting per command. Long-running commands must stream or truncate output — buffering a tail -f or a large build log into memory is a predictable OOM.
Failure modes to instrument.
Ramp-up. Low for any Laravel-fluent engineer — the API is idiomatic and the mental model is familiar. Organizational ramp-up is the real cost: with 18 stars and no external corpus, the team's competence ceiling is set by how well the internal wrapper and runbook are written. Assign a single owner for the abstraction layer and treat it as internal infrastructure with a documented contract, not as a third-party dependency that maintains itself.
How can I help you explore Laravel packages today?