Search by

ion-bazan / composer-diff

IonBazan

Compares composer.lock changes and generates Markdown report so you can use it in PR description.

Package info

github.com/IonBazan/composer-diff

Type:composer-plugin

pkg:composer/ion-bazan/composer-diff

Fund package maintenance!

IonBazan

Statistics

Installs: 2 340 961

Dependents: 1

Suggesters: 2

Stars: 188

Open Issues: 0

v2.4.0 2026-10-05 10:51 UTC

README

PHP 7.2+ | 8.x Composer v2 Dependencies: 0 Latest version GitHub Workflow Status Codecov Mutation testing badge Downloads License

Generates packages changes report in Markdown format by comparing composer.lock files. Compares with last-committed changes by default.

Now available as GitHub Action!

Web version available at https://lyrixx.github.io/composer-diff

preview

Installation

composer global require ion-bazan/composer-diff

If you are using Composer v1 (deprecated) or PHP version older than 7.2, please refer to version 1.x of this package which offers compatibility with PHP 5.3+.

Usage

composer diff # Displays packages changed in current git tree compared with HEAD
composer diff --help # Display detailed usage instructions

Example output

Prod Packages Operation Base Target
psr/event-dispatcher New - 1.0.0
symfony/deprecation-contracts New - v2.1.2
symfony/event-dispatcher Upgraded v2.8.52 v5.1.2
symfony/event-dispatcher-contracts New - v2.1.2
symfony/polyfill-php80 New - v1.17.1
php New - >=5.3
php (effective) Changed >=7.2 <8.0 >=7.2.5 <8.0
Dev Packages Operation Base Target
phpunit/php-code-coverage Downgraded 8.0.2 7.0.10
phpunit/php-file-iterator Downgraded 3.0.2 2.0.2
phpunit/php-text-template Downgraded 2.0.1 1.2.1
phpunit/php-timer Downgraded 5.0.0 2.1.2
phpunit/php-token-stream Downgraded 4.0.2 3.1.1
phpunit/phpunit Downgraded 9.2.5 8.5.8
sebastian/code-unit-reverse-lookup Downgraded 2.0.1 1.0.1
sebastian/comparator Downgraded 4.0.2 3.0.2
sebastian/diff Downgraded 4.0.1 3.0.2
sebastian/environment Downgraded 5.1.1 4.2.3
sebastian/exporter Downgraded 4.0.1 3.1.2
sebastian/global-state Downgraded 4.0.0 3.0.0
sebastian/object-enumerator Downgraded 4.0.1 3.0.3
sebastian/object-reflector Downgraded 2.0.1 1.1.1
sebastian/recursion-context Downgraded 4.0.1 3.0.0
sebastian/resource-operations Downgraded 3.0.1 2.0.1
sebastian/type Downgraded 2.1.0 1.1.3
sebastian/version Downgraded 3.0.0 2.0.1
php (effective) Changed >=7.3 <8.0 >=7.2.5 <8.0
phpunit/php-invoker Removed 3.0.1 -
sebastian/code-unit Removed 1.0.3 -

Options

  • --base (-b) - path, URL or git ref to original composer.lock file
  • --target (-t) - path, URL or git ref to modified composer.lock file
  • --no-dev - ignore dev dependencies (require-dev)
  • --no-prod - ignore prod dependencies (require)
  • --direct (-D) - only show direct dependencies
  • --with-platform (-p) - include platform dependencies (PHP, extensions, etc.), see Platform requirements
  • --with-links (-l) - include compare/release URLs
  • --with-licenses (-c) - include license information
  • --format (-f) - output format (mdtable, mdlist, json, csv, github, pr or one added by an extension) - default: mdtable
  • --gitlab-domains - custom gitlab domains for compare/release URLs - default: use composer config
  • --filter - limit output to packages matching the given glob pattern (e.g. symfony/*); can be specified multiple times
  • --sort - sort packages alphabetically by name; use --sort=operation to group by operation type (installs, upgrades, downgrades, removals)
  • --allow-missing - treat missing composer.lock files as empty (all target packages reported as new installs)

Advanced usage

composer diff master # Compare current composer.lock with the one on master branch
composer diff master:composer.lock develop:composer.lock -p # Compare master and develop branches, including platform dependencies
composer diff --no-dev # ignore dev dependencies
composer diff -p # include platform dependencies
composer diff -f json # Output as JSON instead of table
composer diff -f csv > changes.csv # Save as CSV for spreadsheets
composer diff -f pr # Collapsible <details> blocks for GitHub PR descriptions
composer diff --filter="symfony/*" # Show only symfony packages
composer diff --filter="symfony/*" --filter="doctrine/*" # Show symfony and doctrine packages
composer diff --sort # Sort packages alphabetically by name
composer diff --sort=operation # Group packages by operation type (installs, upgrades, downgrades, removals)
composer diff HEAD:new-dir/composer.lock composer.lock --allow-missing # Compare against a lockfile that doesn't exist on the base ref

You can find more documentation in the docs directory.

Platform requirements

With --with-platform (-p), the report includes two kinds of platform rows:

  • Rows like php show your project's own requirements from composer.json, exactly as written.
  • Rows like php (effective) show the version range required by your project and all locked packages together, for example >=7.2.5 <8.0. They are listed for every platform package that at least one locked package requires, and reveal changes that come from dependencies, such as a package raising its minimum PHP version.
Prod Packages Operation Base Target
php Changed >=7.4 >=8.0
php (effective) Changed >=8.0 <9.0 >=8.1 <9.0

A few details:

  • The dev effective range covers both prod and dev packages, as both are installed in development. When both tables are shown, a dev row is hidden if the prod table already lists the same change.
  • Requirements satisfied by a locked package through provide or replace (for example symfony/polyfill-mbstring providing ext-mbstring) are not listed as effective rows. The provided version is not checked against the requirement.
  • Requirements on Composer itself (composer-plugin-api, composer-runtime-api, and composer when running Composer 2.2 or newer), usually coming from Composer plugins, are listed like any other platform package.
  • If the requirements have no common version range, which can happen in lock files created with --ignore-platform-reqs, the row shows conflicting (N constraints).
  • Effective rows are never marked as direct dependencies, so --direct hides them.
  • Effective rows are always shown as Changed, never as upgrades or downgrades. With --strict, a change in a dependency's platform requirements sets the change flags (2 or 4) even when your own requirements did not change.
  • In JSON and CSV output, effective rows keep the plain platform name (for example php) and are marked with "effective": true (the last effective column in CSV). Formatters show them as php (effective), and JSON uses that label as the row key.

Strict mode

To help you control your dependencies, you may pass --strict option when running in CI. If there are any changes detected, a non-zero exit code will be returned.

Exit code of the command is built using following bit flags:

  • 0 - OK.
  • 1 - General error.
  • 2 - There were changes in prod packages.
  • 4 - There were changes is dev packages.
  • 8 - There were downgrades in prod packages.
  • 16 - There were downgrades in dev packages.

You may check for individual flags or simply check if the status is greater or equal 8 if you don't want to downgrade any package.

With --with-platform, changes in the effective platform requirements of your dependencies also count as changes.

Extensions

Other packages can add output formats and URL generators, and a post-composer-diff event lets you filter results or fail the command with your own rules. See Extensions.

Contributing

Composer Diff is an open source project that welcomes pull requests and issues from anyone. Before opening pull requests, please consider reading our short Contribution Guidelines.

Similar packages

While there are several existing packages offering similar functionality:

This package offers:

  • Support for wide range of PHP versions, starting from 7.2 up to 8.5 and newer (v1.x supports PHP 5.3.2+).
  • No dependencies if you run it as composer plugin.
  • Both standalone executable and composer plugin interface - you choose how you want to use it.
  • Allows generating reports in several formats.
  • Extra Gitlab domains support.
  • Custom formatters, URL generators and a post-diff event through extensions.
  • GitHub Action with example workflow
  • 100% test coverage.
  • MIT license.