Note: This blog post was written in 2015 to cover Drupal 8.0, and is no longer up to date. Composer Manager is deprecated and should not be used. Here’s an updated version.

We’re making a new site based on Drupal 8. This site needs to display addresses, and some quick research leads us to the Address module.

However, after downloading and trying to enable Address, we get the following message: Address requires the commerceguys/addressing library.

In the old days a requirement like this would be satisfied by manually downloading and extracting the library into sites/all/libraries/addressing. Nowadays that’s no longer possible, PHP libraries must be installed using Composer.

What’s Composer?

Composer is a tool for managing dependencies on the project level, a project being your site or web application.

Let’s say our (non-Drupal) site needs the commerceguys/intl and commerceguys/addressing libraries (“packages” in Composer-speak). We would create a composer.json file, and list the dependencies there:

{ "require": { "commerceguys/intl": "dev-master", "commerceguys/addressing": "dev-master" } }

Available packages are listed on Packagist, a central repository anyone can add to. Running composer install will download the dependencies:

Loading composer repositories with package information Installing dependencies (including require-dev) - Installing commerceguys/intl (dev-master d4dca7e) Cloning d4dca7e4d8e5d5cee65c0e987e650daa056f3948 - Installing commerceguys/enum (v1.0) Loading from cache - Installing doctrine/collections (v1.3.0) Loading from cache - Installing commerceguys/addressing (dev-master 98e2cae) Cloning 98e2caedbd71a838a7b2ececbe7691d480b0f6a5 Writing lock file Generating autoload file

Notice how Composer has installed two more packages we didn’t ask for.

Those are the dependencies of our dependencies. You can see them listed in the commerceguys/addressing composer.json file.

Once installed, packages can be kept up to date by running composer update.

Composer knows which versions it’s allowed to install/update to by looking at the composer.json file. The dev-master in our examples means that it should always fetch the latest dev release. We could instead use wildcards to allow only releases of a specific branch.

If you’ve ever used Drush Make to download Drupal modules and themes, then all of this sounds familiar. You can think of Composer as the more advanced Drush Make that works for all PHP projects and packages. Compared to Drush Make, Composer has the benefit of being able to recursively resolve dependencies (downloading the dependencies of each dependency) and being able to detect conflicts.

For example, let’s say package A and package B both require Guzzle, the HTTP client. However, package A specifies that it only works with Guzzle5, while package B specifies that it only works with Guzzle6. In this case Composer will abort the install process and warn us.

Composer is clearly an awesome tool, but why do we NEED to use it? Using Drush Make was always optional for site builders. The secret lies in the last line of Composer output: Generating autoload files.

Modern applications such as Drupal 8 consist of many classes, so it would be impractical and costly to manually include each one. Instead, the application includes one special class, called the autoloader which then automatically includes other classes when they are first needed. When Composer runs, it regenerates the autoloader, giving it the locations of the newly downloaded dependencies.

Inside the folder where we ran composer install there’s now a vendor directory containing both our dependencies and the autoloader.



We can commit this folder to git, or even better, run Composer on every deploy, to ensure our dependencies are fresh. People on shared hosting will need to run Composer locally and commit/upload the result, while others will find running Composer on the server more convenient.

Drupal and Composer

Now that we know how Composer works, let’s use it to download the dependencies for Address. Inside the Address module folder there’s a composer.json file listing the required packages.

Can we run composer install inside and call it a day? No.

We would end up with multiple, possibly conflicting vendor directories on the same site, one for core and one for each module that has Composer dependencies. There can be only one. Instead, we need to run Composer at the root of the Drupal install. There’s already a composer.json file there, ready to be edited.

Here’s how that composer.json file looks like by default, trimmed for sanity:

{ "name": "drupal/drupal", "type": "project", "require": { "composer/installers": "^1.0.21", "wikimedia/composer-merge-plugin": "^1.3.0" }, "replace": { "drupal/core": "~8.0" }, "minimum-stability": "dev", "prefer-stable": true, "extra": { "merge-plugin": { "include": [ "core/composer.json" ], "recurse": false, "replace": false, "merge-extra": false } } }

The first requirement (composer/installers) ensures Composer knows where to put the downloaded drupal modules and themes, so that they don’t end up in the vendor directory.

The second requirement (wikimedia/composer-merge-plugin) allows other composer.json files (listed under extra/merge-plugin/include) to be merged when Composer runs. By default it’s used to merge the core requirements from core/composer.json, but can be used to merge module requirements as well.

This gives us two options for getting the Address requirements:

Composer Manager

Composer Manager discovers each module’s composer.json file and adds it to the above mentioned merge list.

cd mysiteroot drush dl composer_manager php modules/composer_manager/scripts/init.php composer drupal-update

And we’re done. The vendor directory now contains our module’s dependencies.

Once we decide to install another module with Composer dependencies, for example Drupal Commerce, we just need to download that module, then run composer drupal-update again.

For more details, check out the Composer Manager documentation.

Sugar-free Composer

The second option is to treat the root composer.json file as a real Drush Make alternative, and add entire modules as requirements.

"require": { "composer/installers": "^1.0.21", "wikimedia/composer-merge-plugin": "^1.3.0", "drupal/address": "8.1.*@dev" },

Thanks to Composer’s recursive dependency resolving, the libraries required by the module will be automatically downloaded as well.

The next thing we need to do is add the Drupal Packagist repository to the file:

"repositories": [ { "type": "composer", "url": "https://packagist.drupal-composer.org" } ],

This will allow Composer to find the listed Drupal modules.

This is a temporary measure, once Drupal Packagist gets moved to drupal.org, the root composer.json will come with the repository included by default.

We can now run composer update. This downloads the address module to modules/.

The next time we need to add a module or theme, we can take a shortcut:

composer require drupal/address 8.1.*@dev

This will add the line to the ‘require’ section of composer.json, then download just that specific requirement and its dependencies.

The sugar-free method brings a lot more convenience, since core, modules, themes can now be managed using the same powerful mechanism.

For more details, check out the documentation.

Sugar-free, tarball-free Composer

If Composer downloads everything for us, then there’s no need to actually start from a Drupal tarball. We can use the composer create-project command instead which will give us the structure we need:

composer create-project drupal-composer/drupal-project:8.x-dev myproject --stability dev --no-interaction

This creates a myproject directory with a slightly different project layout:



There’s once again a composer.json file and a matching vendor directory, but the actual Drupal install has been moved a level deeper, into the web directory.

The project comes with Drush and Drupal Console. They can always be removed by editing composer.json and running composer update.

Conclusion

Composer is here to stay, and it’s time we got familiar with it.

Due to its power, more and more modules are choosing to separate pieces of their logic into separate packages that can be used by the wider PHP community. They’re also choosing to depend on other people’s libraries in order to reduce their own workload.

There is also no doubt that Composer will replace Drush Make, and make itself the preferred way of assembling sites. Advanced Drupal hosting services like Platform.sh (wink wink) already support it.

In the meantime people who already started making sites without Composer can rely on Composer Manager to get required dependencies without altering their existing workflows.