Interactive dependency update checker for Composer, inspired by npm-check-updates.
composer outdated tells you what's newer. composer update only moves you
within your version ranges. This plugin shows both kinds of updates at
once — those satisfying your composer.json constraints and those beyond
them (new minors/majors) — lets you pick updates with the arrow keys and
Space, rewrites composer.json where needed, and runs composer update for
exactly what you selected.
? Choose which packages to update · ↑/↓ move · Space select · a all · n none · Enter apply · q quit
In range satisfies composer.json — plain `composer update` would pick these
❯ ◉ monolog/monolog 1.25.0 → 1.27.1 (or 3.10.0, see Major)
Minor backwards-compatible features · composer.json will be updated
◯ phpunit/phpunit (dev) 11.5.2 → 11.9.1
Major potentially breaking changes · composer.json will be updated
◯ monolog/monolog 1.25.0 → 3.10.0 (or 1.27.1, see In range)
◯ psr/log 1.0.0 → 3.0.2
1 of 4 selected
composer require --dev webworkerjoshua/composer-check-updatesComposer will ask you to trust the plugin (allow-plugins); confirm with yes.
Install once, use in every project:
composer global require webworkerjoshua/composer-check-updatesGlobally installed Composer plugins are loaded for every composer
invocation, so composer check-updates / composer ccu then works in any
project directory. The global install also provides a bare ccu command —
make sure Composer's global bin directory is on your PATH (find it with
composer global config bin-dir --absolute, typically
~/.composer/vendor/bin on macOS):
cd /path/to/any/project
ccu # same as: composer check-updates
ccu --dry-runcomposer check-updates # interactive picker (alias: composer ccu)- ↑/↓ (or j/k) move, Space selects, a selects all, n selects none, Enter applies, q/Esc/Ctrl-C aborts without changing anything.
- Selecting an entry from In range leaves
composer.jsonuntouched and just runscomposer update <package>. - Selecting an entry from Patch/Minor/Major first rewrites the constraint
in
composer.json(preserving your style:^1.2becomes^3.10,1.2.*becomes3.10.*, exact pins stay exact pins) and then runscomposer update <packages> --with-all-dependencies.
A package like monolog/monolog with constraint ^1.0, installed at
1.25.0, has two distinct upgrade paths: 1.27.1 (in range) and 3.10.0
(major). It therefore appears twice — once in In range and once in
Major — and each entry cross-references the other (or 3.10.0, see Major). The two entries are mutually exclusive: selecting one automatically
deselects the other, so you always make exactly one decision per package.
a (select all) prefers the in-range entry — majors stay opt-in.
Below 1.0.0, a minor bump (0.1.0 → 0.2.0) is shown as Major: semver
makes no compatibility promise for 0.x, and Composer's ^0.1.0 does not
allow 0.2.0 either. Patch bumps within the same 0.x minor stay patches.
composer check-updates --filter "symfony/*" # only matching packages (repeatable, -f)
composer check-updates --reject "phpunit/*" # skip matching packages (repeatable, -x)
composer check-updates --dev-only # only require-dev
composer check-updates --prod-only # only requirePatterns support * wildcards and match case-insensitively; rejects win
over filters.
composer check-updates --dry-run # list only, change nothing
composer check-updates --format json # machine-readable listing
composer check-updates --all # apply everything, prefer latest
composer check-updates --all --target in-range # apply everything, stay in range
composer check-updates --ignore-platform-reqs # ignore php/ext requirementsWhen stdout is not a TTY (CI, pipes) the command prints the grouped listing instead of starting the picker.
The plugin uses Composer's own resolver APIs (RepositorySet +
VersionSelector), so it sees exactly the packages your project sees:
custom repositories, minimum-stability, stability flags, and platform
requirements (your PHP version and extensions) are all respected. For each
root requirement it asks for the best candidate within your constraint and
the best candidate overall; composer.json edits go through Composer's
JsonManipulator, which preserves your file's formatting.
- PHP >= 8.3
- Composer >= 2.3
composer install
composer test # Pest test suite
composer stan # PHPStan static analysis (level max)
composer check # bothMIT