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 type | Commit composer.lock? | Why |
|---|---|---|
| Web application or service | Yes | You deploy one set of versions and want it repeatable |
| Internal tool run by your team | Yes | Same reasoning as an application |
| Library published to Packagist | Optional | Users of your library ignore your lock file and resolve their own |
| Library with a CI matrix | Your call | A 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
- Run
composer updateon purpose, in its own pull request. - Read the composer.lock diff for unexpected packages or large jumps.
- Run an advisory check against the locked set.
- Merge, then let CI and production run
composer installonly.
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
- Composer: Basic usage
- Composer: Command line interface
- Composer FAQ: Should I commit the dependencies in my vendor directory
Last reviewed: 19 October 2026.