A powerful CLI tool for visualizing changes in Composer dependencies after running composer update
. Compare two composer.lock
files and see exactly what packages were added, removed, upgraded, or downgraded with beautiful output formatting and direct links to changelogs.
- Features
- Installation
- Basic Usage
- Help Description
- Output Examples
- Advanced Usage
- Requirements
- Architecture
- Development
- Roadmap
- License
- See Also
- Visual Dependency Tracking: See exactly what changed after
composer update
with color-coded output - Multiple Output Formats: Console tables, Markdown for PRs, or JSON for automation and CI/CD pipelines
- Smart Version Detection: Automatically detects upgrades, downgrades, new, removed, and changed packages
- Direct Links to Changes: Generates comparison URLs for GitHub, GitLab, and Bitbucket repositories
- Environment Filtering: Compare production (
require
) and development (require-dev
) dependencies separately or together - Git Integration: Compare current lock file with any git reference (HEAD, branches, tags)
- Dev Package Support: Handles dev branches with commit hash detection and comparison
- CI/CD Friendly: Perfect for automated workflows, deployment pipelines, and Pull Request automation
- PHAR Distribution: Standalone executable or Composer installation options
# Install for specific project
composer require jbzoo/composer-diff
# Install globally
composer global require jbzoo/composer-diff
# Download latest release
wget https://github.com/JBZoo/Composer-Diff/releases/latest/download/composer-diff.phar
# Make it executable
chmod +x composer-diff.phar
# Update your dependencies first
composer update
# Show what changed (compares HEAD:composer.lock with ./composer.lock)
composer-diff
# If installed locally in project
php ./vendor/bin/composer-diff
# If using PHAR file
php composer-diff.phar
./vendor/bin/composer-diff --help
Description:
Show difference between two versions of composer.lock files
Usage:
diff [options]
Options:
--source=SOURCE The file, git ref, or git ref with filename to compare FROM [default: "HEAD:composer.lock"]
--target=TARGET The file, git ref, or git ref with filename to compare TO [default: "./composer.lock"]
--env=ENV Show only selected environment. Available options: both, require, require-dev [default: "both"]
--output=OUTPUT Output format. Available options: console, markdown, json [default: "console"]
--no-links Hide all links in tables
--strict Return exit code if you have any difference
--no-progress Disable progress bar animation for logs. It will be used only for text output format.
--mute-errors Mute any sort of errors. So exit code will be always "0" (if it's possible).
It has major priority then --non-zero-on-error. It's on your own risk!
--stdout-only For any errors messages application will use StdOut instead of StdErr. It's on your own risk!
--non-zero-on-error None-zero exit code on any StdErr message.
--timestamp Show timestamp at the beginning of each message.It will be used only for text output format.
--profile Display timing and memory usage information.
--output-mode=OUTPUT-MODE Output format. Available options:
text - Default text output format, userfriendly and easy to read.
cron - Shortcut for crontab. It's basically focused on human-readable logs output.
It's combination of --timestamp --profile --stdout-only --no-progress -vv.
logstash - Logstash output format, for integration with ELK stack.
[default: "text"]
--cron Alias for --output-mode=cron. Deprecated!
-h, --help Display help for the given command. When no command is given display help for the diff command
--silent Do not output any message
-q, --quiet Only errors are displayed. All other output is suppressed
-V, --version Display this application version
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
PHP Production Dependencies (require)
+-------------------+------------+--------------------+---------------------+---------------------------------------------------------------+
| Package | Action | Old Version | New Version | Details |
+-------------------+------------+--------------------+---------------------+---------------------------------------------------------------+
| vendor/downgraded | Downgraded | 2.0.0 | 1.0.0 | https://gitlab.com/vendor/downgraded/compare/2.0.0...1.0.0 |
| vendor/new | New | - | 1.0.0 | |
| vendor/no-tag | Changed | dev-master@bbc0fba | dev-master@f2f9280 | https://gitlab.com/vendor/package-1/compare/bbc0fba...f2f9280 |
| vendor/no-tag-new | New | - | dev-develop@a999014 | |
| vendor/removed | Removed | 1.0.0 | - | |
| vendor/upgraded | Upgraded | 1.0.0 | 2.0.0 | https://gitlab.com/vendor/upgraded/compare/1.0.0...2.0.0 |
+-------------------+------------+--------------------+---------------------+---------------------------------------------------------------+
Also, see colored example in travis-ci
Source code:
## PHP Production Dependencies (require)
| Package | Action | Old Version | New Version | |
|:-----------------------------------------------------------|:-----------|-------------------:|--------------------:|:-----------------------------------------------------------------------------|
| [vendor/downgraded](https://gitlab.com/vendor/downgraded) | Downgraded | 2.0.0 | 1.0.0 | [See details](https://gitlab.com/vendor/downgraded/compare/2.0.0...1.0.0) |
| [vendor/new](https://gitlab.com/vendor/new) | New | - | 1.0.0 | |
| [vendor/no-tag](https://gitlab.com/vendor/package-1) | Changed | dev-master@bbc0fba | dev-master@f2f9280 | [See details](https://gitlab.com/vendor/package-1/compare/bbc0fba...f2f9280) |
| [vendor/no-tag-new](https://gitlab.com/vendor-1/package-1) | New | - | dev-develop@a999014 | |
| [vendor/removed](https://gitlab.com/vendor/removed) | Removed | 1.0.0 | - | |
| [vendor/upgraded](https://gitlab.com/vendor/upgraded) | Upgraded | 1.0.0 | 2.0.0 | [See details](https://gitlab.com/vendor/upgraded/compare/1.0.0...2.0.0) |
Rendered in your readme or PR/MR description:
Package | Action | Old Version | New Version | |
---|---|---|---|---|
vendor/downgraded | Downgraded | 2.0.0 | 1.0.0 | See details |
vendor/new | New | - | 1.0.0 | |
vendor/no-tag | Changed | dev-master@bbc0fba | dev-master@f2f9280 | See details |
vendor/no-tag-new | New | - | dev-develop@a999014 | |
vendor/removed | Removed | 1.0.0 | - | |
vendor/upgraded | Upgraded | 1.0.0 | 2.0.0 | See details |
{
"require": {
"vendor\/downgraded": {
"name": "vendor\/downgraded",
"url": "https:\/\/gitlab.com\/vendor\/downgraded",
"version_from": "2.0.0",
"version_to": "1.0.0",
"mode": "Downgraded",
"compare": "https:\/\/gitlab.com\/vendor\/downgraded\/compare\/2.0.0...1.0.0"
},
"vendor\/new": {
"name": "vendor\/new",
"url": "https:\/\/gitlab.com\/vendor\/new",
"version_from": null,
"version_to": "1.0.0",
"mode": "New",
"compare": null
},
"vendor\/no-tag": {
"name": "vendor\/no-tag",
"url": "https:\/\/gitlab.com\/vendor\/package-1",
"version_from": "dev-master@bbc0fba",
"version_to": "dev-master@f2f9280",
"mode": "Changed",
"compare": "https:\/\/gitlab.com\/vendor\/package-1\/compare\/bbc0fba...f2f9280"
},
"vendor\/no-tag-new": {
"name": "vendor\/no-tag-new",
"url": "https:\/\/gitlab.com\/vendor-1\/package-1",
"version_from": null,
"version_to": "dev-develop@a999014",
"mode": "New",
"compare": null
},
"vendor\/removed": {
"name": "vendor\/removed",
"url": "https:\/\/gitlab.com\/vendor\/removed",
"version_from": "1.0.0",
"version_to": null,
"mode": "Removed",
"compare": null
},
"vendor\/upgraded": {
"name": "vendor\/upgraded",
"url": "https:\/\/gitlab.com\/vendor\/upgraded",
"version_from": "1.0.0",
"version_to": "2.0.0",
"mode": "Upgraded",
"compare": "https:\/\/gitlab.com\/vendor\/upgraded\/compare\/1.0.0...2.0.0"
}
}
}
# Compare two specific composer.lock files
composer-diff --source="old/composer.lock" --target="new/composer.lock"
# Compare Git references
composer-diff --source="HEAD~1:composer.lock" --target="HEAD:composer.lock"
# Compare with specific branch or tag
composer-diff --source="v1.0.0:composer.lock" --target="./composer.lock"
# Production dependencies only
composer-diff --env=require
# Development dependencies only
composer-diff --env=require-dev
# Both environments (default)
composer-diff --env=both
# Markdown output for Pull Requests
composer-diff --output=markdown
# JSON output for automation
composer-diff --output=json
# Hide comparison links
composer-diff --no-links
# Strict mode (exit code 1 if differences found)
composer-diff --strict
# Generate PR description after update
composer update
composer-diff --output=markdown >> pr-description.md
# CI/CD pipeline check
composer-diff --strict --output=json > changes.json
# Compare major version upgrades
composer-diff --source="tags/v1.0:composer.lock" --target="tags/v2.0:composer.lock"
- PHP: ^8.2
- Extensions: ext-json, ext-filter
- Composer: ^2.0 (for development)
The tool is built with a clean, object-oriented architecture:
DiffAction
: Main CLI command handler (Symfony Console)Comparator
: Orchestrates comparison between composer.lock filesComposerLock
: Parses and manages composer.lock dataPackage
: Represents individual packages with version handlingDiff
: Compares package versions and determines change typesUrl
: Generates comparison URLs for Git hosting platforms- Renderers: Multiple output formats (Console, Markdown, JSON)
The tool intelligently categorizes changes:
- New: Package added to dependencies
- Removed: Package removed from dependencies
- Upgraded: Semantic version increased (1.0.0 → 2.0.0)
- Downgraded: Semantic version decreased (2.0.0 → 1.0.0)
- Changed: Dev branches with different commit hashes
- Same: No changes (filtered out by default)
Automatically generates comparison URLs for:
- GitHub:
github.com/user/repo/compare/v1.0.0...v2.0.0
- GitLab:
gitlab.com/user/repo/compare/v1.0.0...v2.0.0
- Bitbucket:
bitbucket.org/user/repo/branches/compare/v1.0.0%0Dv2.0.0
# Clone and install dependencies
git clone https://github.com/JBZoo/Composer-Diff.git
cd Composer-Diff
make build
# Run all tests
make test-all
# Run specific test suites
make test # PHPUnit tests
make test-drupal # Real Drupal upgrade test
make test-manual # Manual output examples
make codestyle # Code quality checks
# Build standalone PHAR executable
make build-phar
# Create symlink for local testing
make create-symlink
- Supporting Drupal repos. For example.
- Add action in the composer via API like
composer lock-diff
. - Fixes the same issue with complex/custom name of tag.
- Auto-detecting alias name of branch.
- No warp links for Markdown format.
- (?) Support MS Windows...
make build
make test-all
MIT
- CI-Report-Converter - Converting different error reports for deep compatibility with popular CI systems.
- Composer-Graph - Dependency graph visualization of composer.json based on mermaid-js.
- Mermaid-PHP - Generate diagrams and flowcharts with the help of the mermaid script language.
- Utils - Collection of useful PHP functions, mini-classes, and snippets for every day.
- Image - Package provides object-oriented way to manipulate with images as simple as possible.
- Data - Extended implementation of ArrayObject. Use files as config/array.
- Retry - Tiny PHP library providing retry/backoff functionality with multiple backoff strategies and jitter support.
- SimpleTypes - Converting any values and measures - money, weight, exchange rates, length, ...
Special thanks to the project davidrjonas/composer-lock-diff which inspired me to make a great utility :)