composer & npm · zero config · MIT

Know what you
just shipped.

composer update rewrites four thousand lines of lockfile and tells you nothing. whatsdiff reads that diff, fetches the release notes behind every version bump, and names the security advisories you just inherited. In your terminal, in CI, and in whatever AI you code with.

$composer global require whatsdiff/whatsdiff
Read the docs →
2
Ecosystems, one pass
7
Commands
4
MCP tools for your AI
0
Config files
~/projects/acme-shop — zsh
acme-shop git:(deps/october)
4,312 lines changed in composer.lock. Good luck.
 
Uncommitted changes detected on composer.lock
 
composer.lock between b76fddb and uncommitted changes
 
↑↑ laravel/framework v12.4.1 v12.9.0
↑↑↑ livewire/livewire 3.6.4 4.0.1
symfony/console v7.2.1 v7.2.6
symfony/cache v8.0.5 v8.0.12
↓↓↓ psr/http-message 2.0 1.1
+ php-mcp/server 2.3.1
+ react/promise v3.3.0
× spatie/ray 1.41.2
 
acme-shop git:(deps/october)
$ git diff composer.lock The same change, twice

A lockfile diff is not a changelog.

Git shows you every byte that moved: reordered hashes, shifted dist URLs, re-serialised autoload maps. None of it answers the only question you have, which is whether the thing you are about to merge is safe.

$ git diff composer.lock 4,312 lines · unreadable
$ whatsdiff analyse 8 changes · read it in 5s
composer.lock between b76fddb and HEAD
 
↑↑ laravel/framework v12.4.1 → v12.9.0
↑↑↑ livewire/livewire 3.6.4 → 4.0.1
symfony/console v7.2.1 → v7.2.6
symfony/cache v8.0.5 → v8.0.12
↓↓↓ psr/http-message 2.0 → 1.1
+ php-mcp/server 2.3.1
+ react/promise v3.3.0
× spatie/ray 1.41.2
$ whatsdiff --help Seven commands
$ whatsdiff changelog Release notes, fetched

It reads the release notes so you don't have to.

A version number tells you a package moved. It doesn't tell you that a component dropped PHP 8.1, or that a method you call now behaves differently. whatsdiff walks every version between the two you have and pulls the actual notes.

Every version in between. Jump four releases and you get all four sets of notes, not only the newest one.
Grouped by what it means. Changes, fixes, and removals separated, so breaking news reads first.
Browsable. whatsdiff tui puts the package list and its changelog side by side in your terminal.
changelog docs →
whatsdiff tui
➤ Release Notes Summary
─────────────────────────────────────────
 
Releases: 3.0.3 → 3.0.0 (4 versions)
 
Changes:
This project now uses PHPStan instead of
Psalm for static analysis
 
Fixes:
#9: `Mapper::stringToCodeUnits()` does not
find method when a function is defined
#8: `Mapper` ignores trait inheritance
 
Removed:
No longer supported on PHP 8.1
 
─────────────────────────────────────────
MAJOR sebastian/code-unit 2.0.0 → 3.0.3
$ whatsdiff audit Advisories, both ecosystems
whatsdiff audit --from=main
2 vulnerable packages, 4 security advisories
 
undici 7.15.0 → fixed in 7.29.0
CVE-2026-13697 cross-user information disclosure
and parse-time crash via degenerate headers
CVE-2026-16728 downstream response
desynchronization via retry interceptor
 
tar-fs 3.0.5 → fixed in 3.1.1
CVE-2025-59343 symlink validation bypass when
the destination directory is predictable
CVE-2025-48387 can extract outside the
specified dir with a crafted tarball
 
Legend: high (3) medium (1)

Catch the advisory in the pull request, not in production.

audit resolves every installed version against the advisory registries, filters by the ranges that actually affect you, and works out the lowest safe upgrade for each one.

! Only what this change introduced. --from and --to report the advisories a branch adds, so your pipeline stops re-flagging the backlog.
! One pass, both lockfiles. Composer and npm together, instead of two commands and two output formats.
! Your threshold, your build. --fail-on=high lets low findings through and blocks the ones that matter.
audit docs →
$ whatsdiff check && whatsdiff-mcp Scripts and assistants
In your pipeline

One question, one exit code.

check asks whether a single package moved and exits with a matching code, so a shell script can decide for itself. Skip the rebuild, the restart, and the downtime that comes with them when nothing changed.

# only rebuild assets when a JS dep moved
whatsdiff check vite --is-updated --quiet \
  && npm run build

# fail the job on a new high-severity advisory
whatsdiff audit --from=origin/main --fail-on=high
exit 0
The condition is true
exit 1
The condition is false
exit 2
Not a git repository, or bad input
check docs →
In your editor

Your assistant stops guessing at version numbers.

The same install ships whatsdiff-mcp, a Model Context Protocol server that gives Claude, ChatGPT, Cursor or Zed four tools that read Packagist and npm directly.

you  → which Livewire versions work with Laravel 11?

tool → find_compatible_versions
       package: livewire/livewire
       against: illuminate/support ^11.0

 livewire/livewire 3.x requires ^11.0
  answered from the registry, not from memory
find_compatible_versions
What works with what
get_release_notes
Aggregated notes between two versions
get_available_upgrades
Latest patch, minor and major from where you are
get_dependency_constraints
What a specific version requires
MCP docs →
no terminal required whatsdiff × Unolia
Unolia whatsdiff, bundled in

You'll forget to run it.
Unolia won't.

whatsdiff is a command you type, so it only tells you things on the days you remember to ask. Unolia runs it across every project you maintain, on every deploy and on a schedule, then comes to you when something moves.

+
Every project, not one repository
Point Unolia at the sites you already manage. It tracks dependency changes across all of them in one view, without you cloning a thing.
+
Alerted the day it lands
A new advisory in a package you ship reaches you that morning, instead of during next quarter's audit.
+
In the pull request
Unolia posts the change summary and the advisories where the review happens, so a reviewer sees the major bump before approving it.
+
Next to everything else about that project
Dependencies sit alongside DNS, SSL, deployments, servers and costs, so when something breaks you check one place instead of six.

The CLI and the MCP server stay free and MIT-licensed. Automation is the part you pay for.

$ composer global require One line, then it works

Find out what you shipped.

Installs the CLI and the MCP server together. Run it in any repository with a lockfile. There is nothing else to set up.

$composer global require whatsdiff/whatsdiff

On a CI runner, or a machine you're only visiting once, run it through cpx instead and install nothing at all.

$cpx whatsdiff/whatsdiff analyse
PHP 8.3+ Composer composer.lock package-lock.json MIT