How to upgrade Drupal 9 to 10

Upgrading Drupal from version 9 to version 10 is a multi-step process that involves several different tasks. The process is similar to upgrading Drupal 8 to version 9 so if you already upgraded your Drupal 8 website to version 9, doing an upgrade to version 10 should be relatively easy.

The newest version of Drupal includes many new features and enhancements. I would also like to draw your attention to my article about Drupal 10 features.

1. System requirements

Since this is a major upgrade checking Drupal 10 system requirements is a must! Make sure that your server meets these requirements before you start the upgrade process. The most important requirement is PHP 8.1.

But before you upgrade your server to PHP 8.1 check if all modules and packages support this version. Otherwise, you may encounter errors like this when you run a Composer command.

Problem 1
    - ocramius/package-versions is locked to version 2.3.1 and an update of this package was not requested.
    - ocramius/package-versions 2.3.1 requires php ~8.0.0 -> your php version (8.1.13) does not satisfy that requirement.

Also, be prepared that you might encounter some unexpected issues. When I upgraded PHP on my server from version 8.0 to 8.1, I was greeted with the following error:

Undefined constant PDO::MYSQL_ATTR_USE_BUFFERED_QUERY in Drupal\mysql\Driver\Database\mysql\Connection::open()

Upon investigation, it turned out that there was an issue with the php8.1-mysql extension. I had to reinstall it to resolve the problem.

If you are using Nginx, you might need to update your configuration file. Check the following change record (CR) to find out what needs to be changed: https://www.drupal.org/node/2888767#nginx-php-fpm

The telltale sign that you need to update the Nginx configuration file is if your theme is broken and your browser's console is filled with errors like this:

Failed to load resource: net::ERR_TOO_MANY_REDIRECTS /sites/default/files...
Uncaught ReferenceError: drupalSettings is not defined

I also had to update the location @rewrite section, which is not documented in the change record above. What worked for me in Drupal 8 and 9 is not working with Drupal 10.

Before:

location @rewrite {
  rewrite ^/(.*)$ /index.php?q=$1;
}

After:

location @rewrite {
  rewrite ^ /index.php;
}

Before you can upgrade your website to Drupal 10, you'll need to make sure you're running the latest version of Drupal 9. Don't try to update the website if you are on Drupal 9.1 or some old and unsupported version like that! You should be at least on version 9.4.x to make the upgrade process smoother and reduce the chances of encountering any issues along the way.

Also, just as always before doing an upgrade make a backup of your Drupal site. This will allow you to roll back if anything goes wrong during the upgrade process.

2. Upgrade Status - Check for compatibility

The last time we were using the drupal-check command line tool to check for code deprecations, but this time let's use the Upgrade Status module. Install it by using Composer:

composer require drupal/upgrade_status

and then enable it using Drush:

drush en upgrade_status

Go to the following page: /admin/reports/upgrade-status and check the report for your custom modules and themes. In my case, I'm updating this website (gorannikolovski.com) and I have one custom module and one custom theme.

Image

As you can see both projects are incompatible with Drupal 10. I ran a scan and the result was that I had to make two small changes to make them compatible with the latest version of Drupal.

Image

All I had to do was to update the info files and change from this:

core_version_requirement: ^9

to this:

core_version_requirement: ^9 | ^10

Keeping your custom modules up to date with new standards and removing deprecated code as soon as possible will result in such small changes when you have to do a major core upgrade. Your deprecation report might be much bigger with much more things that you have to fix if your code is not regularly maintained.

As soon as we are sure that our custom code is compatible with Drupal 10, we can move to check the contrib code. And this is where things might get tricky.

Image

You are instructed by the Upgrade Status module to first update all your contrib modules, so use the Composer to do it. The new versions may or may not be Drupal 10 ready. Since we are doing a major core upgrade there is no reason to not do a full update of all modules and packages to the latest versions:

composer update

Now go back to the Upgrade Status report and check what COLLABORATE WITH MAINTAINERS section says. If you see anything here that means that at the moment there is no easy way to upgrade your website to Drupal 10.

Image

All these contrib modules are not compatible with the latest version of Drupal. So essentially I'm blocked at the moment and I can't proceed with the core upgrade.

I'm not in a rush to upgrade to version 10, but if you are then you have several options. Consider using an alternative contrib module compatible with Drupal 10 or remove it altogether from your project if it's not essential. You can add it back later on when it gets compatible with Drupal 10. For example, I can remove the Configuration Read-only module since it doesn't provide anything essential to me.

Another option is to use a patch to make a module Drupal 10 ready. You can most likely find the patch in the issue queue of the module on Drupal.org or you can create it yourself.

Update to Drupal 9.5

In the meantime, until all modules are Drupal 10 compatible, I updated my website to version 9.5.

Image

Drupal 9.5 is more or less the same as version 10.0 -- the key difference is that Drupal 10.0 does not include any deprecated code, while Drupal 9.5 does. Another key difference is that Drupal 10 depends on Symfony 6 while Drupal 9.5 depends on Symfony 4.

3. Upgrade to Drupal 10 with Composer

3.1 Deprecated core themes

You most likely don't want to use the Seven administration theme for your Drupal 10 website, as it is old and outdated. So, before upgrading to Drupal 10, make sure to uninstall it. Go to admin/appearance and uninstall the theme. If you really need the theme after all, then you can install it with Composer because it is available as a contributed theme for Drupal 10:

composer require drupal/seven

The Classy base theme is also deprecated and has been removed from Drupal 10. If you have a custom or contributed theme that depends on it, then before upgrading to Drupal, make sure to install the Classy theme with Composer:

composer require drupal/classy

3.2 Final upgrade

If you fixed all your custom modules and themes and don't have any compatibility issues with contrib projects, then you can proceed with the upgrade. The best way to do it is to use Composer.

Edit your composer.json file and update version constraints for drupal/core-* packages to ^10.

Image

You can now run the composer update command to initiate the upgrade process. Don't forget to also execute the drush updb command to perform database updates.

How to install modules that are not Drupal 10 compatible?

Thanks to Matt Glaman we have a Composer plugin that will let you install modules that are not yet D10-ready. First, install the plugin:

composer require mglaman/composer-drupal-lenient

then proceed with adding a module to the allowed list by executing another Composer command:

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

Finally, add a patch that will make the module D10-ready. In this example, the Node View Permissions module has a simple patch that will make it compatible with the latest version of Drupal.

Image

As you can see in the screenshot above, the second command that we executed created a new section called drupal-lenient. This is the place where you have to add all modules you want to have a lenient Drupal core version constraint.

If you're interested, check out my blog post on how to apply patches in Drupal.

And that's a wrap. You now have all information you need to successfully update your project(s) to the latest and greatest iteration of the best CMS on the planet.

About the Author

Goran Nikolovski is a web and AI developer with over 10 years of expertise in PHP, Drupal, Python, JavaScript, React, and React Native. He founded this website and enjoys sharing his knowledge.