Using Composer to manage Drupal site dependencies

Last updated on
9 February 2017

Composer can be used to download Drupal, Drupal contributed projects (modules, themes, etc.) and all of their respective dependencies. These instructions vary based on your approach to managing your Drupal installation.

Installing Composer

You need Composer to be installed on your local machine before executing any Composer commands. Please see Getting Started on getcomposer.org to install Composer itself.

Creating a new Drupal site

Starting a new Drupal installation using Composer create-project

You may use Composer to download Drupal itself. There are two templates that can be used to generate your new Drupal site via Composer:

  1. drupal/drupal. This uses Drupal itself as a template for the new site. It is the simplest solution but lacks additional configuration that can be helpful.
  2. drupal-composer/drupal-project. This open source project acts as a kickstarter for Composer-based Drupal sites. It provides default configuration that otherwise needs to be added manually.

A brief comparison of the two "template" projects.

Available starting templates

feature drupal/drupal drupal-composer/drupal-project
open source yes yes
directory structure docroot is repo root docroot is subdir
installer-paths config no yes
repositories config no yes
updates scaffold files no yes
includes drush no yes
includes drupal console no yes

Scaffold files

These are files that belong to Drupal but are not in the "core" subdirectory. E.g., .htaccess, robots.txt, index.php, update.php, etc. If you use drupal/drupalas the template for your new Composer project, there will be no Composer-based mechanism for updating scaffold files during a core update. drupal-composer/drupal-project, on the other hand, manages scaffold files for you by default using drupal-composer/drupal-scaffold.

How to create your project

Using drupal-composer/drupal-project

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

This will download the drupal-composer/drupal-project project into a folder named my_site_name and then execute composer install.

You are now ready to download dependencies from either packagist.org or drupal.org.

Follow the instructions for drupal-composer/drupal-project to learn more about it's configuration and features.

Using drupal/drupal

composer create-project drupal/drupal my_site_name 8.1.*@dev --no-dev

This will download the drupal/drupal project into a folder named my_site_name and then execute composer install.

You may now use composer to download dependencies from packagist.org. However, you must modify your composer.json file in order to download module, theme, and other Drupal-specific dependencies from Drupal.org. See Using Composer to manage Drupal site contributed dependencies below.

Starting a new Drupal installation from a git-cloned drupal/drupal

Clone Drupal and execute composer installinside of the repository directory. 

This will download Drupal's composer dependencies into the vendor directory.

You may now use composer to download dependencies from packagist.org. However, you must modify your composer.json file in order to download module, theme, and other Drupal-specific dependencies from Drupal.org. See Using Composer to manage Drupal site contributed dependencies below.

Starting a new Drupal installation from a Tarball

Your Drupal installation already contains Drupal core's dependencies.

You may now use composer to download dependencies from packagist.org. However, you must modify your composer.json file in order to download module, theme, and other Drupal-specific dependencies from Drupal.org. See Using Composer to manage Drupal site contributed dependencies below.

Managing an existing site via Composer

If you initially created your Drupal website without composer, you must modify your composer.json file in order to download module, theme, and other Drupal-specific dependencies from Drupal.org.

You should modify the composer.json file that is at the root of your git repository, not core/composer.json.

Please take a moment to review the available starting templates listed above. You may want to modify your Drupal application's configuration to emulate one these templates. For instance, you may want to take advantage of the drupal-composer/drupal-scaffold package, or choose to place your composer.json above the docroot.

Follow Using Composer to manage Drupal site contributed dependencies in order to make the necessary modifications to your composer.json file.

Using Composer to manage Drupal site contributed dependencies

Using Composer to manage contributed dependencies for a Drupal site is unique. It requires some Drupal-specific configuration in your composer.json file, namely:

  1. Define Drupal.org as the source of drupal packages
  2. Define the directories to which Drupal projects should be downloaded

If you are using drupal-composer/drupal-project as a template for your Drupal site, this configuration is already handled for you. Otherwise, you will need to manually modify your Drupal site's composer.json to include this configuration.

Define Drupal.org as the source of drupal packages

By default, Composer uses Packagist to discover packages. Packagist is a repository of metadata about PHP and PHP-related projects. 

Drupal projects are not listed on Packagist. Instead, Drupal.org provides its own directory of Drupal projects for Composer to use. Therefore you will need to add Drupal.org as a Composer Repository to your Drupal site's composer.json file.

Do not confuse your Drupal site's composer.json (located in your repository root) with Drupal core's composer.json (located in the core directory) or the composer.json belonging to a contributed project.

Drupal.org provides two separate composer repository endpoints: one for Drupal 7 and one for Drupal 8.

  • To use Composer with Drupal 7, use the repository url:https://packages.drupal.org/7
  • To use Composer with Drupal 8, use the repository url:https://packages.drupal.org/8

To add the repository from the command line you should execute the following command from your repository root:

$ composer config repositories.drupal composer https://packages.drupal.org/8 

Composer will then automatically update your Drupal site's composer.json file with a repositories object of the format:

{ 
    "repositories": { 
        "drupal": {
            "type": "composer",
            "url": "https://packages.drupal.org/8" 
        }
    }
} 

This will configure composer to look up Drupal modules, themes, etc. from Drupal.org. Once you have added the appropriate Drupal.org composer endpoint for the version of Drupal you wish to use, you can use Composer as you would use it for any other PHP project.

Unofficial Drupal Packagist

Please note that there is also an unofficial Packagist fork. This uses different version constraints and cannot be used in combination with Drupal.org's official Packagist repository. It does, however, have the advantage of working with contributed profiles.

Define the directories to which Drupal projects should be downloaded

By default, Composer will download all packages to the "vendor" directory. Clearly, this doesn't jibe with Drupal modules, themes, profiles, and libraries. To ensure that packages are downloaded to the correct path, Drupal uses the composer/installers package. Just add the following to your composer.json to configure the directories for your Drupal site:

"extra": {
    "installer-paths": {
        "modules/contrib/{$name}": ["type:drupal-module"],
        "modules/custom/{$name}": ["type:drupal-custom-module"],
        "profiles/contrib/{$name}": ["type:drupal-profile"],
        "themes/contrib/{$name}": ["type:drupal-theme"],
        "themes/custom/{$name}": ["type:drupal-custom-theme"],
        "libraries/{$name}": ["type:drupal-library"],
        "drush/{$name}": ["type:drupal-drush"]
    }
}

Note

Custom modules and themes paths requires composer/installers package v1.0.24 and up.

Define the directories for arbitrary packages that do not have a "drupal-*" type

If you would like to place an arbitrary Composer package in a custom directory, you may use the Composer Installers Extender.

For instance, if you'd like to place the Dropzone package (which does not have a type of drupal-library) in the same directory as other Drupal libraries, you would first composer require oomphinc/composer-installers-extender, then add the following configuration to your composer.json file:

"extra": {
    "installer-paths": {
        "libraries/{$name}": [
            "type:drupal-library",
            "enyo/dropzone"
        ],
    }
}

Finally, you would composer require enyo/dropzone.

How can I add Drupal modules and themes to my site with composer?

To download Drupal modules or themes for your site with composer, enter the following command at the root of your Drupal install:

$ composer require drupal/<modulename> 

For example:

$ composer require drupal/token 

Composer will then automatically update your composer.json file with a require statement of the format:

{
    "require": { 
        "drupal/token": "1.x-dev"
    }
} 

Composer will download the module files but won't actually install it for you - to enable a module, use drush en <modulename> -y  and to check status use drush pm-list

You can use either the project name, or the specific module name within a project when requiring modules. Composer will download the whole project that contains a particular module.

For example, if you need the fe_block module from the features_extra project (https://drupal.org/project/features_extra), you can either

$ composer require drupal/features_extra 

Or use just the module name

$ composer require drupal/fe_block 

It's best to be explicit by using the specific module name when you can.

Specifying a version

you can specify a version from the command line with:

$ composer require drupal/<modulename>:<version> 

For example:

$ composer require drupal/ctools:3.0.0-alpha26
$ composer require drupal/token:1.x-dev 

In these examples, the composer version 3.0.0-alpha26 maps to the drupal.org version 8.x-3.0-alpha26 and 1.x-dev maps to 8.x-1.x branch on drupal.org.

If you specify a branch, such as 1.x you must add -dev to the end of the version.

Tip

To avoid problems on different terminals/shells, surround the version using double quotes. Also, to make sure you will require versions of your dependencies that will guarantee not to break other things, try to use the best combination to constrain versions. Check an example:

$ composer require "drupal/ctools:^3.0@alpha" 

This example will make sure you are installing Ctools 3.x, where x would be the most recent major version of it. In case that Ctools 4 gets released, it will not be updated when you do updates to your project.

In the future, when proper semantic version will be supported by all Drupal.org projects, we will better target on the minor version, like "^3.0.0@beta" for example, as the minor is supposed to guarantee that nothing breaks (that is just security or critical bugs fixing) and you should manually test updates towards new major versions, as the history of PHP with Composer has proven that we don't always work in a utopic environment.

For the sake of your clients, try to avoid version combinations that on updates might bring serious problems and hours of investigations from where it broke.

Doesn't Composer require Semantic Versioning? What about Contrib projects?

Drupal.org contributed projects are currently not versioned with true Semantic Versioning. However, the Composer service on Drupal.org translates the Contrib project version schema, into a semver format that Composer can understand. This 'semver shim' will also allow Drupal.org to be flexible if the versioning standard for Contrib changes.

The key element to this shim is that each major version of Drupal Core has a separate endpoint, to prevent collisions between the D7 version of a module and the D8 version

Example D7 Endpoint Version Mapping
Current Format Translated Format
{Platform.x}-{major}.{minor}-{stability#} {major}.{minor}.0-{stability}{#}
7.x-3.4-beta2 3.4.0-beta2
7.x-2.10-rc2 2.10.0-rc2
7.x-1.0-unstable3 unstable releases will not be translated, and not available to composer
7.x-1.0-alpha5 1.0.0-alpha5
7.x-0.1-rc2 0.1.0-rc2
7.x-1.x-dev 1.x-dev

Using Composer search

Drupal.org's composer endpoints for Drupal 7 and Drupal 8 both support the Composer search function - so you can also search for Drupal projects from the command line. The format for using Composer search is:

composer search views 

Using Composer browse

Drupal.org's composer endpoints for Drupal 7 and Drupal 8 both support the Composer browse function - so you can find additional information about Drupal projects from the command line. The format for using Composer browse is:

composer browse drupal/token 

Patching projects using Composer

You can automatically apply patches to composer-built dependencies using cweagans/composer-patches. See the project's README.md file for specific instructions.