Safeguard
Supply Chain•

Should you commit composer.lock? Applications versus libraries

Commit composer.lock for applications so every install gets the same versions. For libraries it is optional. Here is why, and what it means for security.

Safeguard Security Team
3 min read

Yes, commit composer.lock for any PHP application. It records the exact version of every package, so each developer, CI run and server installs the same code. For a library you publish, the Composer docs say committing it is not necessary, because consumers resolve their own versions.

What the lock file does

composer.json says what you are willing to accept, such as a range of versions. composer.lock says what you actually got on the day someone last ran update. When a lock file exists, install reads the exact versions from it instead of picking the newest match. The Composer documentation calls this by design, so a project does not break from unexpected dependency changes.

That same behaviour is a security control. A package that publishes a bad release tomorrow does not reach your servers until a person runs an update and reviews the diff.

Application or library: a quick guide

Project typeCommit composer.lock?Why
Web application or serviceYesYou deploy one set of versions and want it repeatable
Internal tool run by your teamYesSame reasoning as an application
Library published to PackagistOptionalUsers of your library ignore your lock file and resolve their own
Library with a CI matrixYour callA lock file can hide breakage against newer dependencies

What goes wrong without it

Without a committed lock file, each install has to resolve versions from scratch. Two servers built an hour apart can end up with different code. You also lose the audit trail: a git diff of composer.lock is the plain record of what changed in your dependencies, and reviewers can read it.

A short workflow

  1. Run composer update on purpose, in its own pull request.
  2. Read the composer.lock diff for unexpected packages or large jumps.
  3. Run an advisory check against the locked set.
  4. Merge, then let CI and production run composer install only.
composer validate
composer audit --locked
composer install

The validate command also checks that composer.lock is up to date with composer.json, which catches the case where someone edited one file and forgot the other.

Try it yourself

Click through it at your own pace, or open it full screen. Look at how a lock file turns into a full inventory, including transitive packages you never named.

Where Safeguard fits

Safeguard's SBOM and dependency scanning reads composer.lock and lists direct and transitive packages with known advisories. You can try a free scan.

Quick check

Does composer install change composer.lock?

No. With a lock file present, install uses the versions in it. Running update is what rewrites the lock file.

Should the vendor directory be committed too?

The Composer FAQ recommends against it. Ignore vendor in version control and install from the lock file on each build.

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.