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

Composer Diff Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

ion-bazan/composer-diff is a Composer plugin that adds a composer diff command. It is a narrow, read-only reporting tool: it compares two composer.lock files and emits a Markdown or JSON summary of added, removed, and changed packages. For day-to-day work it is most valuable as a PR/release-notes aid, not as a dependency policy engine.

Install it as a dev dependency:

composer require --dev ion-bazan/composer-diff

Composer 2.2+ will ask whether to allow the plugin. In CI or non-interactive environments, allow it explicitly:

composer config allow-plugins.ion-bazan/composer-diff true

The first command to run is:

composer diff

By default this compares the current composer.lock against the one in HEAD, which is exactly what you want after a local composer update but before committing. To compare two refs:

composer diff --from=origin/main --to=HEAD

The output is a Markdown report, usually split into production and dev dependency changes. The first practical use case is pasting that report into a pull request description:

composer diff --from=origin/main --to=HEAD --format=markdown > composer-diff.md

Look first at composer diff --help, then the repository README and the docs/formatters.md and docs/url-generators.md files. Those document the two features most teams actually care about: machine-readable output and links to upstream version-compare pages. The package requires Composer 2 (composer-plugin-api ^2.0), so it will not help on legacy Composer 1 projects.

Implementation Patterns

Local review after dependency changes. Run composer diff after composer update, composer require, or composer remove. It gives a much clearer summary than reading a raw lock-file diff, especially when a single top-level bump pulls in several transitive updates. Use --no-dev when you only care about production dependencies.

PR body or comment generation in CI. The common workflow is: check out the repo with enough history to resolve the base ref, install dependencies including dev dependencies, run the diff, and publish the Markdown. A GitHub Actions step can append directly to the job summary:

- uses: actions/checkout@v4
  with:
    fetch-depth: 0
- uses: shivammathur/setup-php@v2
  with:
    php-version: '8.3'
- run: composer install --no-interaction
- run: composer diff --from=origin/${{ github.base_ref }} --to=HEAD --format=markdown >> "$GITHUB_STEP_SUMMARY"

If you want an actual PR comment instead of a step summary, write the output to a file and pass it to gh pr comment or a comment action. Keep the generation step non-blocking; the report is informational.

Release notes. For a release branch or tag comparison, use explicit refs:

composer diff --from=v1.4.0 --to=v1.5.0 --format=markdown

This produces a concise dependency-changelog section that can be pasted into release notes. It is especially useful when the release contains grouped Renovate or Dependabot updates.

Machine-readable reporting. Use --format=json when you need to post to Slack, Discord, a custom dashboard, or a bot. Parse the JSON with jq, extract package names and version transitions, and render your own message. This is usually better than trying to postprocess the Markdown table.

Dependency-bot integration. For Renovate or Dependabot PRs, run the diff against the target branch and include the generated table in the PR body. Reviewers can see whether a "minor" bump also changed transitive dependencies, which is often the real risk. If the bot already writes a PR body, append the diff output rather than replacing the existing text.

Upstream compare links. The Markdown formatter can link changed packages to compare pages on GitHub, GitLab, or Bitbucket when the lock file contains a recognized source URL. This is the feature that makes the report genuinely useful during review: a reviewer can jump straight to the upstream diff between the old and new version instead of searching release notes manually. The URL generators are documented in docs/url-generators.md; treat them as best-effort for public, recognized hosts.

Formatter versus post-processing. For most teams, stick to the built-in markdown and json formatters. Custom formatters are an extension point, but unless you need a very specific output format, transforming the JSON outside the package is simpler and keeps you on the supported path.

Gotchas and Tips

  • Shallow clones break ref comparisons. actions/checkout defaults to fetch-depth: 1, so origin/main may not exist. Use fetch-depth: 0 or explicitly fetch the base ref before running composer diff.
  • The plugin must be allowed. Composer 2.2+ blocks plugins by default. If composer install silently omits the command or prompts in CI, add ion-bazan/composer-diff to config.allow-plugins in composer.json.
  • Dev dependency plus --no-dev install is a trap. If the CI job runs composer install --no-dev, the plugin will not be installed. Run the diff job with dev dependencies, or install the plugin separately.
  • Be explicit about refs. The default comparison against HEAD is convenient locally but surprising in CI. Prefer explicit SHAs or fetched branch refs, not moving branch names, for reproducible reports.
  • Both sides need a lock file. Comparing a ref that does not contain composer.lock will fail or produce an empty/odd result. This matters for old tags or branches that did not commit lock files.
  • The exit code is not a policy gate. composer diff reports changes; it is not designed to fail when dependencies change. If you need a gate, wrap it and inspect the output yourself.
  • Watch GitHub comment size limits. Large lock-file updates can produce long tables. GitHub comments have a size limit; the job summary is usually a safer destination, or use --no-dev and filter noisy transitive changes.
  • URL links are best-effort. Private repositories, custom Git hosts, and packages without recognizable source metadata may not get compare links. Do not make the report's usefulness depend on every row being linked.
  • Use JSON for debugging and automation. When the Markdown output looks wrong or you need to inspect exactly what the tool detected, run composer diff --format=json. It exposes the structured data behind the table.
  • Do not confuse it with auditing. This package tells you what changed between lock files. It does not replace composer audit, composer why, or security scanning. Pair it with those tools rather than treating the diff as a risk assessment.
  • Keep the package current. It is a small plugin with a focused surface, but Composer internals and output expectations change. Pin it in composer.lock and update it alongside your other dev tooling.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager