Safeguard
Developer Tools•

Composer install vs update: which should CI and production run?

CI and production should run composer install, which follows composer.lock. Run composer update on purpose, in a reviewed change. Reasons and flags.

Safeguard Security Team
3 min read

CI and production should run composer install. It installs the exact versions in composer.lock. composer update resolves new versions from composer.json and rewrites the lock file, so it belongs in a deliberate, reviewed change, never in a deploy script.

The difference in one table

CommandReadsWrites composer.lockTypical use
installcomposer.lockNo (warns if stale)Build, CI, deploy, new checkout
updatecomposer.jsonYesPlanned dependency refresh
update vendor/packagecomposer.json for that packageYes, for it and what it needsTargeted upgrade or fix

The Composer docs describe update as resolving everything in composer.json, writing exact versions to the lock file, then running install. They also say the very first installation of a project is done with update, which is how the lock file is created.

Why this matters for security

If a deploy script runs update, then your production code is whatever was newest at that minute. That includes a brand new release of a dependency that nobody on your team has seen. A malicious or broken release then lands in production with no pull request, no diff and no review.

With install, a new upstream release changes nothing until someone updates the lock file on purpose.

Useful flags for build boxes

composer install --no-dev --no-interaction
composer install --dry-run
composer install --audit
  • no-dev skips packages in require-dev, so test tools stay off production servers.
  • no-interaction stops Composer waiting for a prompt. The COMPOSER_NO_INTERACTION environment variable does the same on CI.
  • dry-run shows what would happen without changing anything.
  • audit runs an advisory check once installation finishes.

When composer.lock is out of date

If composer.json changed and the lock file did not, install shows a warning. Treat it as a failure in CI. The fix is to run update locally, review, and commit both files. The update command also has a lock option that only refreshes the lock file hash to silence the warning. Use that for a cosmetic change such as a description edit, not as a shortcut past a real dependency change.

A safe update routine

  1. Create a branch and run composer update, or name one package.
  2. Review the composer.lock diff.
  3. Run tests and an advisory check.
  4. Merge. Deploy with install.

Try it yourself

Click through it at your own pace, or open it full screen. Watch how a dependency change in a pull request can be checked before it merges.

Where Safeguard fits

Safeguard's reachability analysis helps separate advisories your code can reach from those it cannot. You can try a free scan on your own lock file.

Quick check

Is it ever fine to run composer update in CI?

Yes, in a scheduled job that opens a pull request with the lock file diff. It is not fine as a step that deploys directly.

What does composer install do with no lock file?

It resolves versions and creates one, the same as update would. Commit it so the next install is repeatable.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.