My thoughts here :
You should never use composer update without argument.
composer update
reads every package listed on composer.json, and updates it to the latest available version compatible with the specified version constraints.
In a perfect world, all librairies would follow semver correctly, and it shouldn't have any side effects. But technically, that is never always true, and you could download a version incompatible with the previous one, or just a version with uncorrected bugs.
So, updating all your packages at once would probably lead to some issues, unless you have the time to check everything on your website to ensure nothing went wrong.
But of course, you'll have to update specific packages sometimes, so using composer update xxx/xxx
is useful, assuming you'll check all your implementations of the package.
When the updated package is fully tested, you can commit your code to staging/production, and then run composer install
to ensure you'll have the same exact version of package and dependencies on all your platforms.
Long story short, here's the process I use :
composer require xxx/xxx
to install new packages
composer update xxx/xxx
to update a specific package
composer install
on all environments when the package.lock file has been updated.
Additional thoughts
I stumbled once upon an implementation which would give the exact version of the package in composer.json. The developer explained that this way you could use composer update
without damage.
I disagree with this option, since even with the exact versions in composer.json, the dependencies are not fixed, and a composer update could lead to potential bugs in them.