Understanding composer.json and composer.lock

When working with PHP projects, dependency management is one of the most critical aspects of maintaining a stable and consistent codebase. Composer is the de facto dependency manager for PHP, and at its core, it relies on two key files: composer.json and composer.lock.

What is composer.json?

The composer.json file is the manifest of your project. It describes the dependencies your project requires, as well as metadata about the project itself.

Key purposes:

  • Define dependencies: Specify the libraries and packages your project needs.
  • Set constraints: Control which versions of dependencies are allowed.
  • Add metadata: Include information such as the project’s name, description, author, license, and more.
  • Define autoloading: Configure how classes are automatically loaded without manual require statements.

Example composer.json

{
  "name": "your-vendor/your-project",
  "description": "A sample PHP project",
  "require": {
    "monolog/monolog": "^2.0",
    "guzzlehttp/guzzle": "^7.0"
  },
  "autoload": {
      "psr-4": {
      "App": "src/"
    }
  }
}

In this example:

  • The project requires monolog/monolog version 2.x and guzzlehttp/guzzle version 7.x or higher.
  • Autoloading is set up for classes in the App namespace.

What is composer.lock?

The composer.lock file is automatically generated when you run composer install or composer update.
Its purpose is to lock the exact versions of all dependencies (including sub-dependencies) to ensure consistency across environments.

Key purposes:

  • Snapshot of dependencies: Records the exact versions of each package installed.
  • Team consistency: Ensures all developers and servers use the same dependency versions.
  • Predictable builds: Makes deployments reliable by preventing unexpected version changes.

Example workflow:

  1. Run composer install – installs dependencies based on the composer.lock file if it exists.
    • If no lock file is present, Composer uses composer.json and generates a lock file.
  2. Run composer update – updates dependencies according to the rules in composer.json and refreshes composer.lock.

The Difference Between composer.json and composer.lock

File Purpose Editable by developer?
composer.json Declares the packages and version ranges your project depends on Yes
composer.lock Stores the exact versions installed to guarantee reproducibility No (auto-generated)

Best Practices

  • Commit both files to version control:
    This ensures your team and CI/CD environments use the same versions of dependencies.
  • Don’t edit composer.lock manually:
    Always let Composer handle it.
  • Use composer install in production:
    This guarantees the exact same dependency versions are installed as in development.
  • Use composer update carefully:
    Only run it when you explicitly want to update dependencies. Afterward, commit the updated composer.lock.