Using Composer With Drupal

Start a new project

composer create-project drupal/recommended-project MYPROJECT

Running this command will create a new project in the MYPROJECT directory.

drupal/recommended-project is a composer project template that will load all require dependencies for Drupal.

See more: https://www.drupal.org/docs/develop/using-composer/starting-a-site-usin….

Minimum stability

In order to install dev, alpha, beta, and release candidate versions, set minimum stability to dev.

Install modules and themes

require

Use require to tell composer that your project requires a dependency.

Drupal modules and themes have the drupal/ namespace, followed by the machine name.

composer require drupal/ctools --update-no-dev

--update-no-dev is used to avoid installing dev dependencies.

update

Use update to update existing dependencies.

composer update -w --no-dev

Security updates

Drupal has a core maintainer team that actively resolves security issues. When vulnerabilities are discovered, they are reported to the team. They work out a patch and facilitate a release and announcement to get sites updated. Once the patch is released, hackers can figure out the vulnerability pretty easily, so it is critical to apply patches.

Sometimes the threat is mitigated already on your site, like a highly trusted user would have to do something bad, or untrusted users don't have a required permission for the exploit. However, you may often not completely understand the risk, or have complete awareness of how the site was built, so it is best to be cautious.

composer.json & composer.lock

When you use composer create-project, it will create a composer.json file, with information about required dependencies.

composer.json

This file define your project's dependencies.

When you require new dependencies, they will get added to this file.

Packages use semantic versioning to specify required versions.

composer.lock

This file tracks the actual versions that are installed. Running composer install on a project will get these same versions instead of calculating dependencies from composer.json.

Patches

Apply patches automatically with cweagans/composer-patches.

Drupal uses a patch contribution workflow, where issues are created and patches uploaded for review. We can apply these patches to our site to fix issues that are not resolved yet in a release.

When using patches, a higher level of attention is needed when applying updates. Hopefully the patch you use gets added to the module and it's downloaded in the next release. Otherwise, you have to check for updates to apply, and review and test if they work.

See also composer-drupal-info-file-patch-helper.

https://packagist.org/packages/orakili/composer-drupal-info-file-patch-helper

Module Dependencies

When fetching a package, composer checks it's *.info.yml and composer.json files for dependencies.

Javascript libraries and external packages need to be defined in a composer repository, which points to the source location.

Path repository

Use a path repository for custom modules.

{
    "type": "path",
    "url": "web/modules/custom/example"
}

https://www.drupal.org/docs/develop/using-composer/managing-dependencies-for-a-custom-project

Git/Github

{
    "type": "package",
    "package": {
        "name": "fooplugins/footable",
        "version": "3.1.6",
        "type": "drupal-library",
        "extra": {
            "installer-name": "footablejs"
        },
        "dist": {
            "url": "https://github.com/fooplugins/footable/archive/refs/tags/3.1.6.zip",
            "type": "zip"
        }
    }
}

Install a specific commit.

composer require drupal/token:dev-BRANCH#COMMIT

Development modules

When you install the dev version of a module, composer clones the repo.

This puts the .git directory inside your project repo, and throws a warning when you try to commit the files.

You shouldn't use a submodule, like git suggests because that would break the composer updates.

Instead, use this post update/install script to remove the .git directories.

"scripts": {
    "post-install-cmd": [
        "find web vendor -name '.git' | xargs rm -rf"
    ],
    "post-update-cmd": [
        "find web vendor -name '.git' | xargs rm -rf"
    ]
},

Composer Installers Plugin

https://github.com/composer/installers

Definitions of composer package types for Drupal and other projects.

Configure install paths for libraries, modules, themes, etc.

Required by Drupal core.

Customize install location: https://github.com/composer/installers?tab=readme-ov-file#custom-install-paths

OomphInc Composer Installers Extender

Additional configuration options for composer installers.

https://github.com/oomphinc/composer-installers-extender

Composer Merge Plugin (Deprecated)

Modules can include a composer.libraries.json file that defines non-drupal dependencies.

To install them, install wikimedia/composer-merge-plugin add the modules's composer.libraries.json path to "extra": {"merge-plugin": {"include": []}}.

Still works but deprecated? Or only deprecated for core use?
https://www.drupal.org/node/3069730
https://github.com/wikimedia/composer-merge-plugin

https://drupal.slack.com/archives/C1BMUQ9U6/p1709942944844569

Lenient Packages

Add modules with an outdated core_version_requirement.

https://www.drupal.org/docs/develop/using-composer/using-drupals-lenient-composer-endpoint

Asset Packagist

Install npm and bower packages using asset-packagist.

Add the asset-packagist repo and installer paths to composer.json.

Install with composer npm-asset/select2.

Merge Requests

Drupal development has started to use merge requests in gitlab. Look out for updates there, as well as in patches in issue queues.

Use parent dir

When in a nested directory, composer will ask if you want to use the root file.

Set this global config setting to skip the prompt and always use it.

https://getcomposer.org/doc/06-config.md#use-parent-dir

Using composer with Lando

If you use a VM like Lando, make sure to run composer inside the box by running:

lando composer install.

Your VM may have a different version of PHP or available extensions, so you could end up with different packages if you install with your host PHP version.

More composer plugins

https://github.com/civicrm/composer-compile-plugin

https://github.com/pyrech/composer-changelogs

https://github.com/fxpio/foxy

More things

This comment mentions Symfony AssetManager.

https://www.drupal.org/project/drupal/issues/2873160#comment-15367880

https://github.com/jakoch/awesome-composer