Developer Quick Tips: Updating Modules Using "composer update" vs "composer require"

composer code snippet

Using Composer to manage your Drupal 8 site makes a lot a things a whole lot simpler. However, as with anything else, Composer certainly has its own learning curve.

If you’re still relatively new to using Composer to manage a Drupal site, Drupal.org has some great documentation already. Once you get the hang of it, you’ll (almost) never want to manage another Drupal site without Composer again.

Assuming you are already comfortable using Composer to manage your Drupal site, you should be more than familiar with how to update contributed modules used within your site. First of all, to check what updates might be available, you can always run the following Drush command, which will output a list of all modules that have more recent releases available for download:

drush ups

You can also run the following Composer command to do something similar, by outputting a list of any outdated Composer packages that correspond to the Drupal modules installed on your site:

composer outdated 'drupal/*'

NOTE: Using the above Composer command can sometimes give you false positives, showing packages as being outdated that Drush may have already claimed are up to date. Just remember that some Drupal modules may have multiple parallel branches that use different minor or major version numbers, but are all still supported by the project maintainer. Another scenario that is somewhat less common, but still relevant, is when a project does not yet have a stable release (the project version still ends in -dev-alpha, or -beta). In that case, Composer may show a package as being outdated simply because your local copy is a few commits behind the upstream repo. While you may want to update your local package to be in line with the very latest commits from a project, you’ll likely need to test such changes very thoroughly before deploying them, since the project itself is not yet stable.

Assuming you have a module that you do actually need to update, the standard command to update the module via Composer will usually do the trick:

composer update drupal/MODULE_NAME --with-dependencies

Here, we are telling Composer to update the Drupal mode as well as any of its dependencies, while respecting any version constraints that we may have placed on the module in our composer.json file. Hopefully, running the composer update command above will give you what you need, and you’ll get to commit the code changes and be on your way! Sadly, though, that may not be the case…

One common issue that you may run into is, after running that standard composer update command, Composer politely informs you that, no, you are actually mistaken and that there is, in fact, “nothing to install or update.” Long story short, Composer is now giving us a false negative: we know that a module is out of date, and yet Composer refuses to believe us.

The culprit in this situation is most likely an over-specified version number in your composer.json file. For example, the module may be locked to a specific version number (e.g., drupal/core:8.6.17), or a specific range of version numbers (e.g., drupal/core:^8.6), that you didn’t intend or no longer want. In you are unfamiliar with these distinctions, or are just a little out of practice, the official Composer documentation on versions is always very helpful to glance at.

To solve this issue, you could go in and manually edit your composer.json file, then run composer update --lock to update your composer.lock file, and then run composer install to make sure the correct version of the module gets installed.

But, personally, I’m too lazy to do all of that manual editing of my composer.json file, since that kind of defeats the purpose of having a command-line tool like Composer installed locally to begin with. Instead, to make things easier on yourself, you can just use composer require, but with a few specific caveats. Specifically, you’ll need to run something like the following command:

composer require drupal/MODULE_NAME:^NEW_VERSION --update-with-dependencies

The key here is, first, to specify the new version number you want (and usually prefix that with a ^ to allow for easier future updates). Second and most importantly, however, we use the flag --update-with-dependencies. This option is basically like a cheat code that gets Composer to run composer update as part of composer require. In our case, that means we get to require the module (rather than update), even though what we are really doing is updating it and its dependencies just like we wanted to begin with.

Et voilà! The module should now be updated. You can now go ahead and commit that changes, and then take a nice long nap after all that hard work.

Image Source