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

Laminas Cli Laravel Package

laminas/laminas-cli

laminas-cli provides a Symfony Console-based command runner for Laminas and Mezzio applications, letting you register CLI commands as services and execute them through a unified laminas-cli binary.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. laminas/laminas-cli is a console kernel, not a library of commands: it resolves a PSR-11 container, reads a laminas-cli.commands config map, and hands the resulting Symfony Console commands to a runner. Laravel already ships an equivalent kernel (Artisan) on the same underlying component (symfony/console). The two therefore compete at the entry-point layer and overlap ~100% functionally in a pure Laravel estate. The only durable architectural value for a Laravel shop is the interchange format: a Symfony\Component\Console\Command\Command subclass is portable between both runners. That reframes the package from "CLI framework" to "a second runner we would only need if we share command code with a non-Laravel application."

Integration feasibility. Technically achievable, low-to-moderate effort:

  • Laravel's container implements PSR-11, so it satisfies the container contract by type. The friction is semantic, not structural: laminas-cli expects a config service returning an associative array, whereas Laravel binds config to Illuminate\Config\Repository. A thin adapter (or a bespoke container file) is required.
  • The --container=<path> global option (added in 1.1.0, hardened in 1.1.1) is the clean seam: a single PHP file can boot Laravel's application kernel and return a PSR-11 wrapper exposing config plus command factories. This avoids monkey-patching the framework.
  • Alternative, cheaper integration: skip laminas-cli entirely and register the same command classes in Artisan via Kernel::$commands. Zero new dependencies.

Technical risk.

Risk Severity Notes
Symfony major churn High 1.10 dropped Symfony 5, 1.14 dropped Symfony 6 and permits 8. Each Laminas minor can invalidate our Laravel version pairing. This is the dominant constraint.
PHP floor drift Medium 1.13 dropped PHP 8.1 and added 8.5. Laravel 10 projects on PHP 8.1 are excluded from current releases.
Dual bootstrapping Medium Two entry points means two config-cache/.env paths that can silently diverge.
Bus factor / velocity Medium Recent releases are almost entirely dependency bumps (Renovate) by 2–3 contributors; feature work is sparse (one attribute-command PR in 1.15.0). Maintenance-mode posture.
Ecosystem signal Medium 56 stars, low dependent count, no first-party Laravel integration. Adoption risk if we later need community answers.
Feature gap vs Artisan Low No scheduling, no --env, no Tinker, no event/discovery parity.

Key questions for the team.

  1. Do we own or acquire any Laminas MVC / Mezzio services? If no, the package has no standing use case.
  2. Is the goal reusing Laminas commands inside Laravel, or sharing our commands with a Laminas app? Only the latter justifies a second runner.
  3. Which Laravel majors are in support, and what is our PHP floor per app? This alone may rule the package in or out.
  4. Who owns the container-adapter file, and is it covered by tests in CI?
  5. Would a framework-agnostic command package (Symfony Console only, no runner) deliver the same reuse at lower coupling cost?

Integration Approach

Stack fit. Poor as a default dependency, viable as a scoped exception. Laravel's idiomatic answer to cross-application command sharing is a Composer package exposing Command classes, consumed by Artisan. laminas-cli should be evaluated only where a Laminas/Mezzio runtime is a first-class target.

Migration path (if we proceed). Use the package as an additive runner, never as a replacement:

  1. Extract the shared command into a standalone package depending only on symfony/console and PSR-11 — no Laminas runner, no Laravel framework.
  2. In Laravel, register those commands in App\Console\Kernel (or via withCommands() in bootstrap/app.php for Laravel 11+ style). No laminas-cli dependency.
  3. Only in the Laminas/Mezzio service do we add laminas/laminas-cli and map the same classes under laminas-cli.commands, with a ServiceManager/dependencies factory entry per command.
  4. If a Laravel-hosted binary genuinely must run Laminas commands, ship a single bin/laminas wrapper that returns a PSR-11 adapter over Illuminate\Container\Container with config projected to an array.

Compatibility (verify against composer.json before committing).

Host PHP symfony/console Highest usable laminas-cli
Laravel 10.x 8.1–8.3 ^6.2 1.13.x (8.1 hosts capped at 1.12.x)
Laravel 11.x 8.2–8.4 ^7.0 1.14–1.15
Laravel 12.x 8.2–8.5 ^7.x 1.14–1.15

Two independent floors (PHP and Symfony Console) must be satisfied simultaneously, and the ceilings move with each Laminas minor. Pin the package to a caret range and gate upgrades on our slowest-moving Laravel major.

Sequencing.

  1. Week 1 — Discovery (2 days). Inventory Laminas/Mezzio footprint across the estate. If zero, close the evaluation.
  2. Week 1 — Spike (2–3 days). In a throwaway Laravel 12 app, add the package, write the --container adapter, run one trivial command, and confirm composer why-not behaviour against our other pinned deps.
  3. Week 2 — Design review. Decide between "shared Symfony Console package" (default recommendation) vs "shared package + Laminas runner on the Laminas side only."
  4. Week 3 — Pilot. Ship one real command through the chosen path in a non-critical service; instrument exit codes and logs.
  5. Week 4+ — Ratchet. Add a CI job asserting the command runs under both runners; document the compatibility table in the repo README.

Operational Impact

Maintenance. Low code surface, ongoing constraint management. The real cost is not the package but the pairing matrix: every Laravel or Laminas upgrade requires re-validating PHP and Symfony Console ranges together. Budget ~1–2 engineer-days per major-version crossing. If the package is only consumed by Laminas services, that cost is contained; if it sits in a Laravel composer.json, it becomes a permanent transitive constraint on framework upgrades.

Support. There is no vendor SLA. Upstream responsiveness is community-driven and skewed toward dependency updates; a Symfony 9 or PHP 8.6 incompatibility would be resolved on maintainer availability, not our timeline. Mitigation: keep the shared command classes free of runner-specific code so a stalled upstream blocks only the runner, not the functionality. Internal ownership must be named explicitly — a platform engineer, not a feature team.

Scaling. Console scaling is about CI and operational fan-out, not request throughput:

  • Each invocation cold-boots a container. Under a Laravel adapter that means a full framework bootstrap; batch jobs should be one process with internal iteration, not N processes.
  • Parallel execution is available via our existing orchestration (queue workers, Kubernetes Jobs, or spatie/fork); laminas-cli adds nothing here and does not implement a --parallel model.
  • The --container file is a per-invocation cost and a per-invocation trust boundary; it must be a checked-in, non-user-supplied path in production.

Failure modes.

Mode Symptom Detection Response
Container adapter drift config service absent or wrong shape → command map empty, "command not found" Smoke test in CI invoking a known command Fail the pipeline; adapter is versioned code
Transitive version conflict composer update blocked on symfony/console composer why-not gate in CI Cap laminas-cli, or drop it from the Laravel app
Dual-bootstrap divergence Command reads stale config-cache / wrong .env Structured log of resolved environment at command start Prefer Artisan for Laravel-hosted jobs
Unmaintained upstream No release covering new PHP/Symfony Renovate/Dependabot alerts unattended Vendor or forklift the runner; commands remain portable
Silent exit-code semantics Non-zero failures masked by wrapper shell scripts Assert exit codes in integration tests Standardise on Symfony Console return codes

Ramp-up. Low for the command API (it is Symfony Console, already familiar to any Laravel engineer writing Artisan commands). Moderate for the Laminas side: mezzio/MVC service-manager factory conventions, module config aggregation, and the laminas-cli.commands map are a distinct mental model from Laravel's service providers and Kernel::$commands. Estimate half a day of onboarding for a Laravel engineer to author a portable command, and roughly a day to confidently operate the Laminas runner. Documentation in the repo is adequate (README plus docs site, referenced by the maturity signal) but assumes Laminas familiarity.

TPM recommendation. Do not adopt as a standard dependency in the Laravel estate. Pursue the narrow version of the opportunity: extract genuinely shared operators into a framework-neutral Symfony Console package, consume it via Artisan in Laravel, and add laminas-cli only to Laminas/Mezzio services that already exist. Re-evaluate if a Laminas footprint materialises or if Artisan proves insufficient for a cross-framework delivery requirement.

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.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table