Running the wrong Composer command can change more dependencies than you intended. The key distinction is straightforward: composer install installs the versions already recorded in composer.lock, while composer update resolves dependency constraints again and writes the resulting versions to that lock file.

What goes into composer.json and composer.lock?

composer.json describes the packages a PHP project needs and the version constraints it accepts. Those constraints are ranges or rules, not necessarily one exact version. The lock file records the specific package versions selected when dependencies were resolved, along with information Composer needs to install them consistently.

For an application, commit both files to version control. Composer explains that keeping the lock file lets developers, CI and production install the same selected dependency versions, which reduces differences between environments. The Composer basic usage guide describes this as a reproducibility benefit.

Use install when setting up or deploying the project

After cloning an application, a developer will usually run composer install. If the lock file exists and matches the project definition, Composer installs the versions it contains. The same command is generally appropriate in CI and deployment builds, so a routine release does not silently pick up newer packages within the allowed constraints.

If the project has no lock file, Composer has to resolve versions from the constraints. For an application, that usually means the repository is missing a file that should be committed; resolve and review dependencies in development, then commit the lock file before relying on repeatable installs.

Use update when intentionally changing dependencies

Run composer update when you mean to refresh dependency selections, such as upgrading packages or resolving a newly added requirement. Composer evaluates the constraints, selects compatible versions and updates the lock file. That can affect transitive dependencies as well as the package you had in mind.

For a smaller change, a targeted update can limit the packages Composer considers, but it can still alter dependencies required by that package. Review the lock-file diff: check what changed, why each version moved and whether the update introduces security fixes or breaking changes. Then run the project’s tests and application checks before merging.

A safe dependency workflow

  1. Make the dependency change on a branch, not directly during a production deployment.

  2. Run the appropriate Composer command and inspect both composer.json and composer.lock.

  3. Review package changelogs and compatibility requirements for notable updates.

  4. Run tests and build checks using the updated lock file.

  5. Commit the reviewed lock file so CI and deployment install the same versions.

Composer’s guidance for caching dependencies in CI reinforces the same pattern: cache downloads to save time, but still run composer install from the lock file in the build.

Applications and libraries differ

An application controls its complete deployment and should normally commit its lock file. A reusable library is different: downstream projects resolve that library alongside their own dependency tree, so the library’s lock file does not control the versions installed in those projects. Composer’s library documentation explains that distinction.

Keep deployment predictable when dependencies change

Do not run a broad composer update as an unreviewed step in a release. It can select newer versions that still satisfy the declared constraints, which means the deployed dependency set may differ from the one exercised in testing. Instead, resolve and review package changes in a development branch, commit the resulting lock file, and have CI and deployment run composer install from that reviewed file.

If composer install warns that the lock file is out of date, check that the package changes in composer.json have been resolved and reflected in the lock file. A merge can leave those files inconsistent even when the conflict markers are gone. Composer’s guide to resolving lock-file conflicts recommends treating the dependency resolution as a deliberate step, then reviewing the resulting change rather than guessing package versions by hand.

A useful rule is to treat composer update as a deliberate change to review and test, and composer install as the repeatable way to reproduce an already-approved dependency set. That makes it easier to understand why a package changed and to reproduce the same application build later.