Using Drupal's Lenient Composer Endpoint

Last updated on
9 January 2024

Background

Since Drupal 9, there are many projects on drupal.org that are compatible with an older version of Drupal, but are not yet compatible with a newer version. Many of these projects have patches available to make them compatible, but the maintainers have not committed them. Both of the following need to be possible to be able to use these projects:

  1. Composer to download the project code
  2. Patches applied to make the code compatible

Typically, site owners would download a project and then patch it to make it compatible, however, https://packages.drupal.org/8 advertises these projects as only being compatible with the earlier version of Drupal, which prevents composer from downloading the project into a codebase with a newer version of Drupal, which in turn prevents them from being patched. So patching alone is not enough; a solution is needed to get around the version constraints which are read from this remote endpoint.

Solutions

A different approach is currently needed when handling upgrades between different major versions of Drupal.

Drupal 9 to Drupal 10

NEW - Use the Lenient Composer Plugin

To install it use:

composer require mglaman/composer-drupal-lenient

This composer plugin lets you specify an allowlist of packages where you are willing to break the version constraint, using a command like:

composer config --merge --json extra.drupal-lenient.allowed-list '["drupal/token"]'

Together with the Composer Patches Plugin, this allows you to install any Drupal extension, even if the version constraint hasn't been officially updated yet. Of course the code may still need to be patched for deprecations. 

Note, when using DrupalPod, first run ddev ssh before the composer config command above, or manually update the allowed-list in thecomposer.json file directly.

Drupal 8 to Drupal 9

The rest of this page is about upgrading from Drupal 8 to Drupal 9. If you are upgrading from Drupal 9 to Drupal 10, then see the note above about the Lenient Composer Plugin.

Drupal.org is now offering a second composer repository endpoint: https://packages.drupal.org/lenient

By adding Drupal's lenient Composer endpoint to their project's composer.json, users will be allowed to require packages that do not have explicitly defined version compatibility - however they will still need to ensure that the appropriate patches are applied so that Drupal itself will allow them to be installed and enabled.

Any project that has not added the core_version_requirement metadata to their project will be advertised at this lenient endpoint without any requirements on drupal/core.  As projects add core_version_requirement, they will be removed from the lenient endpoint, and will fall back to the standard packages.drupal.org.

Caveats

This lenient facade *only* supports Composer 2 because only Composer 2 has the repository priority feature that this relies on to function properly.

Once you add the lenient facade to your codebase, you will receive a warning every time you use composer that you are using it.  Ideally site owners work with the maintainers to make their projects Drupal 9 compatible, and do not simply set and forget this additional endpoint.

Certain composer commands may behave differently once you add the lenient endpoint.  e.g.:$ composer why-not drupal/core:^9 would typically tell you all the projects on your site that prevent you from upgrading to drupal 9.  Most of those projects would now no longer block the upgrade.

As mentioned above, this *only* enables composer to download the project.  The project will still need to be patched to make it actually compatible with Drupal 9. 

Updating the Endpoints in your composer.json

This guide assumes that you have already properly configured your Drupal site to use packages.drupal.org for Composer. 

If you have not yet set up your site to use Composer, first see Using Composer to manage Drupal site dependencies.

Your composer.json repository section for a Drupal 8 or Drupal 9 project should look similar to this before you have added the lenient Composer endpoint: 

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

To add the lenient endpoint, run the following command, or manually edit the composer.json repositories file to the following: 

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

The formatting above may be a little misleading - this composer command should be all on one line, with https://packages.drupal.org/lenient at the end.

Composer.json with lenient endpoint correctly added should look like: 

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

Note that the lenient Composer endpoint must be listed before the standard packages endpoint, so that the relaxed requirements on package version are picked up first when running Composer. 

Workflow to enable Drupal 8 modules in Drupal 9

While the lenient endpoint allows Composer to install or upgrade the packages in a Drupal 9 codebase, they may still need patches to work properly. These steps should allow you to patch any modules appropriately: 

  1. Add the lenient Composer endpoint to your Composer.json file, per the instructions above. 
  2. Composer require or Composer upgrade as you normally would
  3. You will no longer receive a warning that the Drupal 8 module is not compatible with your Drupal 9 codebase - however, Drupal itself will still require that the module be patched. 
  4. If the only patch the module needs is to its info.yml file where it declares compatibility with Drupal 9, the simplest solution may be to install the Backward Compatibility module. 
  5. If additional patching is required, or you prefer not to use the Backward Compatibility module, you can install and use the cweagans/composer-patches package for Composer. Instructions for use are documented on the project page.

You should then be able to upgrade your Drupal 8 site to Drupal 9 with these patched Drupal 8 modules (or install a Drupal 8 module in a Drupal 9 codebase). 

Excluding Packages from the Lenient Endpoint

Note
It should no longer be possible for a package to remain in the lenient endpoint once it has been updated on the primary endpoint. However, if you encounter this issue again, please use the steps below as a temporary solution and reopen: [#3246383]

Some projects may exists in the Drupal 8 composer repository (https://packages.drupal.org/8) as well as the Lenient composer repository (https://packages.drupal.org/lenient) but with a higher repository priority. If the packages with higher priority do not match your constraint they will not be installable. Because both projects have a package with identical names, Composer doesn't know which one the user wants. See https://getcomposer.org/repoprio for details and assistance.

The resulting error will look like this:

Package drupal/module_name exists in composer repo (https://packages.drupal.org/8) and composer repo (https://packages.drupal.org/lenient) which has a higher repository priority. The packages with higher priority do not match your constraint and are therefore not installable. See https://getcomposer.org/repoprio for details and assistance.  
                                                                                                                                                             

To resolve this issue, change the Lenient repository's definition with an explicit exclude argument:

"repositories": {
    "lenient": {
        "type": "composer",
        "url": "https://packages.drupal.org/lenient",
        "exclude": [
            "drupal/module_name"
        ]
    },
    "drupal": {
        "type": "composer",
        "url": "https://packages.drupal.org/8"
    }
}

Help improve this page

Page status: No known problems

You can: