ion-bazan/composer-diff
Composer Diff compares composer.lock files across Git branches, commits, or tags and reports added, removed, and updated Composer packages. Use it to review dependency changes in pull requests and see exactly what a merge will alter in PHP projects.
Architecture fit. composer-diff is a Composer plugin plus a standalone CLI (./composer-diff) that diffs composer.lock between two Git refs and emits a Markdown table of added/removed/upgraded packages, with links to changelogs and compare views. It is a developer-tooling dependency, not a runtime library: it is never loaded by the Laravel application, holds no service-provider or facade surface, and touches nothing in the request lifecycle. That makes it architecture-neutral — the only coupling is to Composer itself and to the repository layout. For a Laravel shop the fit question is therefore not "does it belong in the app?" but "does it belong in require-dev and in CI?"
Integration feasibility. Installation is a single composer require --dev ion-bazan/composer-diff; invocation is either composer diff <base-ref> once the plugin is active or the vendored binary directly. The output is plain Markdown, so it drops into a PR description, a PR comment posted by a CI token, or a build artifact without any downstream transformation. No Laravel, PHP-framework, or hosting assumptions are involved. The realistic effort for a first working pipeline on one repository is a couple of hours.
Technical risk. The dominant risks are supply-chain and bus-factor, not code quality. The project is effectively single-maintainer, has ~188 stars and zero Packagist dependents, which indicates limited independent validation rather than poor quality — its own gates (100% line coverage, 100% MSI via Infection, PHPStan level 7, StyleCI, strict PSR-4) are stronger than most packages of this size. Two concrete friction points: (1) as a Composer plugin it must be added to allow-plugins in composer.json under Composer 2.2+, or it will silently not register its command — a common "it just doesn't work" support ticket; (2) some of its value-add (changelog/compare URLs) implies outbound network calls to hosting APIs during CI, which can fail in air-gapped or rate-limited runners. The declared support window PHP 7.2→8.5 forces the source to avoid PHP 8 syntax, which is a compatibility benefit for heterogeneous fleets and has no downside for Laravel 9+. Treat the advertised last-release date (2026-10-05) and the low composite score against a high opportunity score in your own scoring as diligence items: verify release recency and changelog activity in your internal mirror before standardizing, and treat the package as "high potential value, low adoption" rather than "proven."
Key questions to resolve before proposing it.
vendor/-level forking acceptable (MIT makes this trivial)?allow-plugins posture, and can we add one entry without weakening the policy for everyone?Stack fit. Add as a require-dev package in every Composer-managed Laravel repository. It coexists with existing tooling (Pint, PHPStan, Larastan, Pest/PHPUnit) without conflict, and its dependency ranges — composer/composer ^2.0, composer-plugin-api ^2.0, symfony/console ^5.4 || ^6.0 || ^7.0 || ^8.0 — sit inside the Symfony Console range that Laravel 9/10/11 already resolve. There is no PHP version conflict with any currently supported Laravel release.
Migration path. Purely additive; nothing is replaced. The natural adoption ladder: run it ad hoc on one recent lock-changing PR, then wire it into a single CI job, then template it. Do not attempt a big-bang rollout across all repositories — the value is proven per-repository in minutes and the configuration is small enough that standardization is cheap once the shape is agreed.
Compatibility actions required in the repo.
"ion-bazan/composer-diff": true to the config.allow-plugins block of composer.json (or run with --no-plugins and invoke the binary path directly if policy forbids allowing plugins).composer-plugin-api ^2.0 requirement; a stale composer:1 image is a hard failure.fetch-depth: 0 on actions/checkout is the usual fix), otherwise the diff target does not exist in the clone.Sequencing.
pull_request that generates the report and posts/updates a single PR comment via the platform CLI or API, guarded so it does not run on fork PRs without secrets.Maintenance. Very low steady-state cost: a dev-only dependency, no runtime footprint, no database, no scheduled work, no configuration files to drift. Upgrades are ordinary composer update events. The realistic maintenance obligation is monitoring upstream activity and being prepared to fork — the codebase is small, MIT-licensed, and its own test suite is comprehensive enough that a fork is a low-risk contingency. Budget a recurring quarterly check of the upstream release feed alongside other dev-tooling reviews.
Support. Community-only; there is no vendor to escalate to. Assign ownership to the platform/DevEx function rather than to individual product teams, and document two things internally: the allow-plugins requirement and the required Git history depth. Both are the source of nearly all first-contact failures. Keep the fork-or-replace decision recorded so a future maintainer isn't re-litigating it.
Scaling. Stateless and per-PR; the marginal cost is seconds of CI time and a single API call per posted comment. Two scaling pressures to watch: outbound API rate limits when many repositories post concurrently (changelog/compare URL resolution against a shared hosting account), and monorepos where multiple lock files exist — each needs its own invocation. Neither is a blocker at typical Laravel-org scale, but both should be in the rollout notes.
Failure modes and mitigations.
allow-plugins entry. Detect by asserting the command exists in the CI step; fail loudly rather than emitting an empty report.composer.lock.Ramp-up. Effectively zero for engineers — the output is a Markdown table they read, not a tool they learn. The TPM-facing ramp-up is in adoption, not training: engineers will ignore the report unless it appears automatically in the PR and is visibly referenced in review. Expect roughly half a day to design the reusable workflow and one to two sprints of running it in report-only mode before anyone treats it as a gate. The measurable payout is in dependency-review hygiene — faster security and upgrade reviews, an auditable record of what changed in each release — which is exactly the kind of outcome worth instrumenting (time-to-review on lock-changing PRs, percentage of lock changes with an explicit reviewer) before and after rollout.
How can I help you explore Laravel packages today?