A missing composer.lock file is how "works on my machine" becomes a production incident, and Composer is what keeps it from happening. This covers keeping composer.json, composer.lock and vendor/ aligned while you add, install and audit PHP dependencies, and checking the platform and security state before you hand the project to another machine.
Allow about fifteen minutes for a small project, plus package download time. Examples use Composer 2.7.1, installed here as Debian package composer 2.7.1-2ubuntu0.1~esm1; exact diagnostics and dependency choices vary by release, repository metadata and PHP version. Run these as the project user: root-owned files here are a problem your application user cannot fix later.
Start in the directory containing your project's composer.json. This is read-only:
$ command -v composer
/usr/bin/composer
$ composer --version
Composer version 2.7.1 2024-02-09 15:26:28
$ test -f composer.json && echo 'composer.json found'
composer.json found
If the file lives elsewhere, use the global --working-dir option instead of changing your shell's directory:
$ composer --working-dir=/path/to/project validate
Checkpoint: you have confirmed the binary and the exact directory you intend to change. Do not run a dependency command from a parent directory and hope Composer finds the right project.
Run validate before installing or updating anything. It checks the project metadata and, when present, the lock file:
$ composer validate
./composer.json is valid
./composer.lock is valid
The exact lines depend on whether a lock file exists. A validation failure is a stop sign: fix the JSON or lock file and repeat the command. Warning: do not paper over a schema error by deleting composer.lock, that changes the resolution input and can pull in a different set of packages entirely.
For a checkout that already has composer.lock, use install: Composer uses the exact recorded versions and writes them under vendor/. This is the normal command for a deployment, a fresh checkout, or CI:
$ composer install --no-interaction --no-progress
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Generating autoload files
Output varies by project; what matters is a zero exit status and a real autoloader:
$ printf 'install status: %s\n' "$?"
install status: 0
$ test -f vendor/autoload.php && echo 'autoload ready'
autoload ready
--no-interaction stops prompts in automation.--no-progress keeps terminal control characters out of logs.If the project defines plugins or scripts, installation may run them. For a cautious or restricted build, consider --no-plugins --no-scripts, then run the project's required setup explicitly after reviewing it: those flags can leave a project incomplete if its scripts generate required files.
Use require when the project should start depending on a package. It edits composer.json, resolves dependencies, and normally updates composer.lock and vendor/. Replace the placeholder package and constraint with one you have actually reviewed:
$ composer require vendor/package:^1.2 --no-interaction
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies
Writing lock file
Installing dependencies from lock file
Generating autoload files
Check the change before committing it:
$ git diff -- composer.json composer.lock
$ composer validate
$ composer audit
Warning: require is not a harmless lookup, it downloads code, may run package or project scripts, and can pull in transitive updates to satisfy the new constraint. If the result is wrong, restore the two tracked files from version control and remove the generated vendor changes through your normal recovery process; do not treat composer update as an undo command, it resolves versions again from scratch.
install follows the lock file. update reads the constraints in composer.json, resolves a fresh permitted set of versions, and rewrites composer.lock, making it a deliberate change rather than a routine deployment step:
$ composer update vendor/package --with-dependencies --no-interaction
Loading composer repositories with package information
Updating dependencies
Writing lock file
Installing dependencies from lock file
Generating autoload files
Name a single package when only one direct dependency needs attention; without an argument, Composer considers the whole graph and may update far more than you expected. Review the lock-file diff, run the test suite, and repeat composer audit before committing.
There is no safe universal rollback. The reliable recovery is to restore the previous reviewed composer.json and composer.lock, then run composer install; keep the old lock file until the new setup has passed its checks.
A lock file cannot make an unsuitable PHP runtime suitable. Check platform requirements after an install or when moving to another host:
$ composer check-platform-reqs
No vendor dir present. Please run "composer install" first.
On an installed project it reports each PHP extension and runtime requirement. A failure means the host needs a compatible runtime or extension; --ignore-platform-reqs is not a fix, it can turn an install-time warning into a production failure.
$ composer audit
No security vulnerability advisories found.
The result depends on current advisory data and your actual packages. Treat any advisory as a release decision that needs investigating, not something to suppress just to make a build go green.
Changed the autoload mapping, or added a class under an existing one? Regenerate the autoloader:
$ composer dump-autoload
Generating autoload files
This never chooses new dependency versions. If the mapping is wrong, fix the namespace and path in the project file and run it again. A reviewed --classmap-authoritative or --optimize can change autoload behaviour for production, so treat either as a deliberate choice, not performance folklore.
composer.json by hand can make install warn the lock file is out of date; review the intended constraint and run a planned update rather than ignoring the warning.--working-dir, or check with pwd and ls composer.json, before changing dependencies.--no-plugins or --no-scripts where your build policy requires it.sudo composer; repair ownership through your normal admin process if it has already happened.composer --version and the working directory match what you intend.composer validate succeeds before any dependency change is committed.composer install, not an implicit update.composer check-platform-reqs and composer audit pass, or exceptions are documented.