Composer 2.0 is now available!

1/ What's new?

The list of changes and improvements is long, check the complete changelog if you are interested in reading it all. I will highlight a few key points here.

Performance improvements

We overhauled pretty much everything from the protocol used between Composer and to the dependency resolution, including downloading files in parallel using curl and constraint evaluation optimizations. This leads to massive improvements in terms of both speed and memory usage. The difference depends on your use case, so while I've seen reports of improvements of over 50% to both in some projects, I cannot put an exact number on it. But I am sure you will be positively surprised if you haven't tried Composer 2 yet.

As a side note to this, require/remove and partial updates are now much faster because Composer will now only load the metadata of the packages which are being changed.

Time for initial update + install (bootstrapped project, empty cache) shows roughly 60% less time used by Composer 2 with ext-curl enabled

Architectural changes and determinism

The way dependency updates are done internally was refactored, which, for you, will result in more deterministic updates. The current local state of the vendor directory will not interfere in updates anymore.

After an update is complete, the install process is run automatically and it will now execute all network bound operations first - and in parallel if possible. This will avoid leaving you with a half-updated vendor directory if a network error occurs midway through installation.

Runtime features

We added a platform-check step when vendor/autoload.php gets initialized which checks the current PHP version (and optionally extensions) match what is expected by your dependencies and fails hard otherwise. This is enabled by default so make sure you read up on it to avoid surprises.

There is a new class, Composer\InstalledVersions, which is autoloaded in every project and is available at runtime. It allows you to check which packages/versions are present at runtime of your own project.

See the runtime docs for more details.

If your code relies on any of these runtime features, you should require "composer-runtime-api": "^2.0" in your composer.json. This is a virtual package which is provided by Composer and will make sure people have to use Composer 2.x to install your package.

Error reporting improvements

Because things don't always go the way they're supposed to, we made sure to improve the error reporting shown to you when dependencies cannot be resolved. It's hard to give concrete examples here as there are a million ways this can fail but you will hopefully notice that messages are now shorter, clearer and less repetitive.

Partial updates with temporary constraints

Sometimes it can be useful to upgrade or downgrade a single package to a specific version, perhaps temporarily to test something or wait for a bug fix. You can now run composer update vendor/package:1.0.* for example (or 1.0.12 or any other version constraint), to run an update of only vendor/package to a version matching this additional constraint. This will not update your require in composer.json, and it will not mark the lock file out of date.

If you want to add/restrict a constraint but still do a full update of all dependencies, you can use update --with vendor/package:1.0.* which will run the update with that additional constraint.

2/ How easy is it to upgrade?

Our goal is that every Composer user can upgrade smoothly and swiftly. The gains are huge and we want everyone to benefit from them. To achieve that we did a few things:

  • Composer 2.0 still supports PHP 5.3 and above, much like Composer 1.x
  • composer.lock files are interoperable between versions, so you can upgrade to 2.0 and roll back easily if needed.
  • Most commands and arguments remain the same, and largely what you know about Composer remains true in 2.0.

If you run composer self-update from 1.x, it will warn you that a new stable major version of Composer is available, and you can use composer self-update --2 to migrate to it. You can find specific instructions for various frameworks/CMSs/apps on GitHub which may assist you in upgrading.

Should you encounter issues, you can go back at any time by using composer self-update --1. Hopefully that will make everyone feel comfortable to experiment with the new release.

If you are installing Composer automatically from the installer script, and wish to remain on Composer 1.x for the time being, you can also pass it a --1 argument to prevent it from installing Composer 2.0 by default. If you do this please remember and aim to upgrade in a timely manner, as Composer 1.x will not be maintained for very long.

Seeing Command "self-update" is not defined. ? If you installed Composer via your OS package manager, the self-update command may not be available. Use which composer to find its path (e.g. /usr/bin/composer), then run the install script adding --install-dir /usr/bin --filename composer (adjusting the install dir to match your path) to the php composer-setup.php line.

3/ Backwards compatibility breaks?

Here are the main things likely to cause trouble with the upgrade process:

  • Plugins: This is probably going to be the major source of problems for most people. Plugins need to be updated to support Composer 2, and some of them are not ready, yet. Composer 2 will complain and fail to resolve dependencies if a plugin does not support it, so no need to overthink it, you can try it out and see how it goes.
  • The new platform-check feature means that Composer checks the runtime PHP version and (optionally) available extensions to ensure they match the project dependencies. If a mismatch is found, the autoloader exits with error details to make sure problems are not overlooked. To avoid issues when deploying to production it is recommended to run composer check-platform-reqs with the production PHP process as part of your build or deployment process.
  • Repository priority: If a package exists in a higher priority repository, it will now be entirely ignored in lower priority repositories. If you seem to be missing packages when using Composer 2, see repository priorities docs for details.
  • Invalid PSR-0 / PSR-4 configurations will not autoload anymore in optimized-autoloader mode, as per the warnings introduced in Composer 1.10. Mostly these warnings were for classes that were not meant to autoload anyway so I don't expect major issues, but it's safer to clean these up before upgrading.

If you want to know more, I would highly recommend reading the UPGRADE guide which has multiple sections for end users, plugin authors and Composer repository implementors.

4/ What's next?

We don't have a very detailed feature roadmap anymore as 2.0 contains tons of new goodies, but one important thing I want to explain is our PHP version support going forward.

As I mentioned above, Composer 2.0 supports PHP 5.3+, which is at this point very outdated and makes the code quite hard to maintain in places. We went through the effort to make sure every Composer user can upgrade to Composer 2, but the plan is to drop support for EOL PHP versions in a future minor release.

Composer 2.1 2.2 will still come with PHP 5.3 support, but then for Composer 2.2 2.3 we will drop support for everything older than PHP 7.2.5. According to our stats this allows over 90% of the Composer users to use the latest version, and for the others who are stuck on outdated PHP versions we will keep providing critical bug and security fixes in the 2.2.x range.

As for Composer 1.x, it is now more or less EOL. It will also receive critical fixes if anything comes up but the goal for everyone should be to migrate to 2.x as soon as possible.

Update: You can now read more about the Composer 1.x deprecation timeline.

Finally I want to thank everyone who contributed and helped make this a reality. The 2.0 release represents over 1100 commits from 28 people, 150+ GitHub issues and pull requests, plus everyone who test it, reviewed PRs, etc. It has been a huge effort with the first commits made about two years ago.

I also want to thank all our Private Packagist customers who helped finance this effort and afforded us the time we spent on all this. We sincerely hope everyone will appreciate the result!