drupal 9 to 10 upgrade

Upgrade Drupal 9 to 10 twice as fast (+cheatsheet)

No time to read it now?

We will send a link to the article to your inbox

Read later

The Drupal 10 release took place in December 2022, prompting customers to contact Drupal agencies to request a CMS upgrade. On the official Drupal website, you can find out how many Drupal sites there are in the world and what core version they are working on. You will see that the number of sites running Drupal 10 is currently growing, while the opposite is true for its predecessors.

How long does it take to upgrade Drupal?

If you already have a Drupal 9 site, upgrading it to Drupal 10 will take between 20 and 200 hours. The amount of content, the number of contributed and custom modules, profiles, and themes, as well as the availability of third-party services on the site will determine the duration of this process.

The upgrade sequence has long been described and is clear. This takes creativity out of the job, so you will probably want to get it done as soon as possible. Using our best practices, we have compiled guidelines on how to cut the time it takes to upgrade Drupal 9 to 10 by approximately half. 

Developers! Skip the first two sections of the post and start with the Before You Upgrade note. 

If you develop or own a site built on an outdated version of Drupal and are planning to update Drupal core or have never even thought about it, this post will be useful to you.

upgrading drupal core

Upgrading Drupal core

Why upgrade your Drupal core version?

Just imagine: You’re outside. You've known this town, this neighborhood, and the street for many years, and before you, your parents lived here. You remember when this place used to be cleaner and safer, but now even rubbish collectors and policemen rarely come here. The area is teeming with criminals. People who have lost their way will leave this place without their money and phones at best. What can be done? You can fight the gangs, set up a volunteer patrol, and replace broken windows with new ones. Alternatively, you can move to another district or town where the government maintains order. And you can do this as quickly as possible.

Sites running on outdated and unsupported versions of Drupal are, in a sense, like formerly prosperous but now socially deprived districts. What are the owners of nearly 15,000 sites built on Drupal 6 doing to keep them running? Do they really issue security patches for modules that are no longer supported by the core developers and the community? You can try and keep the interface up to date, but it will be of no use if hackers get in through the broken windows of insecure modules and steal gigabytes of data about you and your users.

In general, running a site on an outdated version of Drupal compromises:

  • Cybersecurity. If no one refactors the code on which the module is written and no one writes patches for these modules, a vulnerability is created that hackers can use to do their dirty work on your site. This will show up in your users’ complaints and in the project directories, where additional folders and files containing malicious code will appear. Damage from cyberattacks is estimated at tens of millions of dollars;
  • Functionality. With the advent of a new version of Drupal, designers and developers spend most of their efforts adapting the features of the new version, not the outdated ones, to the spirit of the times. As a result, sites running on older versions of Drupal are just not able to solve modern tasks and boast of a pleasing appearance;
  • Hosting. It is not cost-effective for hosting providers to maintain and service equipment that works with the old version of the PHP language and old versions of databases that previous versions of Drupal used to work with;
  • Third-party service integration. The APIs of all existing services are likely to be tailored to work with modern software. 
drupal upgrade

Drupal 10 upgrade

What it’s like?

Experienced developers will remember that Drupal 8 brought a new approach to updating the core of this CMS. This approach has survived to this day. At the heart of this approach is semantic versioning, i.e., the principle of assigning major, minor, and patch versions to any software, as well as marking versions to indicate the intermediate nature of the upgrade, which may behave incorrectly.

Drupal 8 incorporates components of the Symfony framework, which in turn allows developers to update Drupal through the Composer package manager, which uses semantic versioning. This paved the way for supporting backward compatibility between Drupal versions: bad code is marked but removed gradually, while the developer has time to find a new way to preserve the site functionality maintained by that code. In Drupal 7, outdated code was marked as such. However, this was not a requirement of the system policy, and developers did so at their own discretion.  

To sum up in a nutshell. 

In the past. Although changes to the code were recorded in the documentation of new core releases and the code itself was marked as obsolete, this was not a strict practice. When upgrading the core in Drupal 7 and earlier versions, developers had to rewrite themes and fix custom code. Although the extent of changes depended on the site complexity and amount of custom code, once the Drupal version was updated, this was largely a new site.

Now. With the advent of Drupal 8, the likelihood of unpredictable core upgrade errors has decreased significantly. The entire code base was checked for the presence of untrustworthy code (the so-called deprecation cycle), which was marked as obsolete and up for removal by the site developers. As a result, upgrading to Drupal 10 takes no more time than upgrading to a minor version.

Drupal upgrade or migration?

An important note: All recommendations in this post apply only if you are upgrading Drupal 9 to 10. If the site works on Drupal 7, you can’t just jump to Drupal 10. This is already a site migration and requires different instructions.

Read more: How to upgrade Drupal 7 and Drupal 8 to Drupal 10

upgrading drupal

Before you upgrade to Drupal 10

What you need to know and remember before upgrading to Drupal 10:

  • The site must run on at least Drupal 9.4. Why is it important? If you skip this version and rush to the tenth version from, say, Drupal 9.3, sooner or later your site will stop working due to outdated APIs (Entity API, Database API, and the like).
  • Upgrading reverse dependencies is the key procedure when upgrading to Drupal 10. For this task, the Composer is your best friend.
  • The latest versions of custom and contrib modules are required.
  • To find and fix bugs in the project's PHP code, you need either the PHPStorm integrated development environment or the Upgrade Status module. You should disable the latter just before the update and delete it afterward. 
  • Your server must be technically fit for the new version of CMS. Below you will find requirements for PHP versions, web servers, and databases that Drupal 10 is compatible with.
drupal requirements
  • Use the Database Support for JSON check to make sure that the system and the project will be compatible in the future: open the Reports tab in the Panel and go to the Status Report page, which should be in the Available state. Another way to check compatibility is to use the Upgrade Status module: open the Upgrade Status page in the same Reports tab and read the DRUPAL CORE AND HOSTING ENVIRONMENT report. 
drupal upgrade status

How to upgrade Drupal 9 to 10

Step-by-step guide

1. Update your site to the latest version of Drupal 9 (9.4 or higher)

  • Update the core:

composer update "drupal/core-*" --with-all-dependencies

  • Update all contrib modules in the Composer:

composer update

  • Start the database update:

drush updatedb
drush cache:rebuild

  • Make sure the website is working.
  • Add or update patches as necessary.

2. Upgrade to Drupal 10

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

"require" : {
"composer/installers" : "^2.0"
"drupal/core-composer-scaffold" : "^10" 
"drupal/core-project-message" : "^10" 
"drupal/core-recommend" : "^10"

In addition to the components mentioned above, the composer.json can also include the drupal/core-dev and drupal/core components. 

As soon as you run the composer update, the update will begin. 

3. Apply the compatibility patch to modules without a version for Drupal 10

You can find these patches in the Issues section of the module. The issue itself is called Automated Drupal 10 Compatibility Fixes. After that, you can either edit the core version in composer.json replacing “^10” with “10.0.9 as 9.5.9”, or use the composer drupal lenient plugin.

4. Add obsolete modules and themes

If your site uses modules or themes that have been removed from the Drupal core, add their contrib versions to your composer.json file.

For example, this is the command you can use to add the Bartik theme, which was a default theme since Drupal 7, but was replaced by Olivero in Drupal 10:

composer require 'drupal/bartik:^1.0'

5. Update compatibility versions in custom modules and themes

  • Remove the core line from the my_module.info.yml file, if it exists (e.g. core: 8.x). 
  • Add Version 10 in the core_version_requirement line. For example, instead of the core_version_requirement: ^8 || ^9 there must be core_version_requirement: ^8 || ^9 || ^10.
  • If your site uses an outdated theme as its base theme (for example, the Classy theme), you can change it to the recommended Starterkit theme: replace base theme: classy in my_theme.info.yml with base theme: starterkit_theme. The same applies to the Stable theme, which can be replaced with stable9. In this case it is also necessary to change the library of the base theme in Twig templates if it is used there.
    Example: The line {{ attach_library('classy/node') }} is replaced with {{ attach_library('starterkit_theme/node') }} )
  • Do not forget to enable the starterkit_theme if you have chosen to use it as the base theme. It should appear in the core.extension.yml configuration file. 
  • At the end of the upgrade you can delete the replaced obsolete themes from the composer.json file.
  • Find and remove any obsolete API calls from the PHP code, and fix the code so that only the new API can be used.
    Example: The outdated drupal_get_path('module', 'my_module_name') function is replaced with \Drupal::service('extension.list.module')->getPath('my_module_name').
update compatibility in custom drupal modules

If you are using PHPStorm as your IDE, you can start the code check using PHP_CodeSniffer in the project settings:

  • Install PHP_CodeSniffer using the Composer:

composer global require "squizlabs/php_codesniffer=*"

  • Go to the Code Sniffer settings in the Quality Tools section and set the path to the phpcs and phpcbf files.
  • Select autocheck in Editor → Inspections.

How to find code errors using the Upgrade Status:

  • In the Reports tab, open the Upgrade Status page.
  • Read the contents of the Drupal Core and Hosting Environment section.

6. Twig has been updated to version 3, so you may need to update your Twig files.

Using PHPStorm:

  • Perform the actions one by one: Code → Analyze Code → Run Inspection by name and press Enter. Option 2: SHIFT + SHIFT combination → start typing “Run inspection by name” and press Enter. You will see the Enter inspection name window.
  • Type in the Deprecated Twig extension in the window and press Enter. A modal window will open.
  • In the window, find the Inspection Scope section, select Custom Scope and then select Scope only with your own code.
  • Click OK, wait for the analysis to complete, and look through the files and fragments of obsolete code.

Using the Upgrade Status:

  • In the Reports tab, open the Upgrade Status page.
  • Choose your own modules and themes and click on Scan Selected.
  • Correct any errors found after the scan.

7. Update dependencies in your .libraries.yml files.

For example, if you have the core/jquery.once library in your dependencies, replace it with the core/once library because once is now a separate library. The JS code where once is used should be edited accordingly:

jquery update drupal

8. Make sure your code is not obsolete and meets the requirements of PHP 8.1.

You can use the Upgrade Status module to perform this check. To do this, use Composer to add the phpcompatibility/php-compatibility package to your require-dev section, and once the package is installed, check the code of your module using command:

phpcs -p ./path/to/my/module --extensions=php,module,inc,install,test,profile,theme --standard=vendor/phpcompatibility/php-compatibility/PHPCompatibility --runtime-set testVersion 8.1

If everything is OK, you will see something like this:

drupal php version

9. If you are upgrading Drupal to version 10.1.x, make sure that after updating the configurations in the core.extension.yml file the Password Compatibility (phpass) (Password hashing is changed) module appears. 

10. Start database update 

drush updatedb

After the site update, the Status Report may show the error Mismatched entity and/or field definitions.

updating drupal with drush

You can fix this by inserting the code below into your module and running the update:

 * Implements hook_update_N().
function HOOK_update_8701() {

  $entity_type_manager = \Drupal::entityTypeManager();

  $entity_type_ids = [];
  $change_summary = \Drupal::service('entity.definition_update_manager')->getChangeSummary();
  foreach ($change_summary as $entity_type_id => $change_list) {
    $entity_type = $entity_type_manager->getDefinition($entity_type_id);
    $entity_type_ids[] = $entity_type_id;

  return t("Installed/Updated the entity type(s): @entity_type_ids", [
    '@entity_type_ids' => implode(', ', $entity_type_ids),

There should be no such error in the Status Report.

Cheatsheet for a quick site upgrade to Drupal 10

Our Drupal developer once upgraded a client's website, which was not very large, to Drupal 10. A similar website was in the offing. And how many such or more complex sites will there be in the future? So, to avoid having to remember what she did with this or that module or theme, she created some spreadsheets describing the standard behavior to apply to modules, themes, and configs that might be encountered in projects: replacing with a dev or patch version, applying a hook, marking the module as a contributed one, etc.

Cheatsheet for a quick site upgrade to Drupal 10

The left part of the spreadsheet contains the module or theme installed on the site, and the right part contains the changes that should be made in the composer.json file to make these modules and themes work on Drupal 10. How to interpret the comments on the right:

  • 10.0.9 as 9.5.9: After the compatibility patches have been applied to modules without a version, the core version is edited for Drupal 10: “^10” is changed to “10.0.9 as 9.5.9”.
  • Automated Drupal 10 compatibility fixes patch: If a module or theme does not even have a dev version for Drupal 10, you can either search for a patch in the project’s issues or google the module or theme name along with the issue name: Automated Drupal 10 compatibility fixes patch.
  • 5.x-dev@dev: The module that does not support Drupal 10 has been replaced with a dev version.
  • contrib now: The module no longer exists in the Drupal core, so it is necessary to write it in composer.json. 
update drupal core with composer

This spreadsheet is used to mark some notes about changes in config files. In particular, it describes how the old themes on the site are updated with new ones.

composer config

This spreadsheet records the state of the dependencies before their upgrade in your .libraries.yml, and how they need to be changed. These prompts allowed the developer to update the second site in half the time.

Click the link to find a Google Spreadsheet with the structure ready to be used by you or your developer to make comments on your projects. The spreadsheet is read-only, so make a copy for your own use.

We wish you a smooth and quick upgrade to the latest Drupal version!

You might also like