How to upgrade from Drupal 11 to Drupal 12

Last updated on
19 February 2026

This documentation needs review. See "Help improve this page" in the sidebar.

This is a work in progress prior toDrupal 12 release.

Supported versions

  • Target version: Drupal 12.x
  • Minimum source version: Drupal TBA

Prerequisites

Before beginning the upgrade, ensure your environment and site meet the following requirements:


1. Prepare for upgrade

Manage scaffold files and deprecations

All Drupal core files (including .htaccess) will change. If you have customized scaffold files, document your changes to reapply them later.

Resolve core modules and themes

Several modules are deprecated in Drupal 11 and removed in Drupal 12:

  • Removed extensions: Ban, Contact, Field Layout, History, Migrate Drupal, Migrate Drupal UI
  • Obsolete extensions: TBA.

Options for handling removed modules:

  1. Stop using the module in Drupal 11 before upgrading.
  2. Install the contributed version of the modules (except Migrate Drupal and Migrate Drupal UI) in Drupal 11.3+ before performing the Drupal 12 code upgrade.

2. Update contributed & custom code

Check compatibility with upgrade status

Use the Upgrade Status module to identify compatibility gaps.

To update a module to a specific version (e.g., drupal/webform), run:

composer require drupal/webform:^6.3 --no-update

If a compatible version isn't found:

  • Check the module's issue queue for Drupal 12 patches. Read "Create a Drupal 11 compatibility patch" for more tips.
  • Use the Drupal Lenient Composer endpoint for modules requiring patches.
  • Multi-version compatibility: You can allow multiple versions in composer.json to bridge the gap. For example, change "drupal/linkit": "^6.1" to "drupal/linkit": "^6.1 || ^7.0"

Update custom code

Use Drupal Rector and Upgrade Status to replace code deprecated in Drupal 10.

Cleanup (optional)

Once compatibility is confirmed, you may remove Upgrade Status and Drush (reinstalling Drush after the upgrade):

drush pm:uninstall upgrade_status -y
composer remove drupal/upgrade_status --no-update

3. Perform the upgrade to Drupal 12

Execute these steps from the Drupal root directory.

Step 1: Open file permissions

chmod u+w web/sites/default
chmod u+w web/sites/default/*settings.php
chmod u+w web/sites/default/*services.yml

Step 2: Update core dependencies

We use --no-update to prevent dependency conflicts while preparing the requirements.

composer require 'drupal/core-recommended:^12' \
'drupal/core-composer-scaffold:^12' \
'drupal/core-project-message:^12' --no-update

If drupal/core is listed explicitly in your composer.json, remove it:

composer remove drupal/core --no-update

Update development tools and Drush:

composer require 'drupal/core-dev:^12' --dev --no-update
composer require 'drush/drush:^13' --no-update

Step 3: Run the update

First, perform a dry run to check for errors:

composer update --dry-run

If successful, execute the actual update:

composer update

Note: To update only core and Drush, use:

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

Step 4: Verify and database update

Ensure the environment is consistent:

composer install

Run pending database updates:

drush updatedb:status
drush updatedb

Step 5: Restore permissions

chmod 755 web/sites/default
chmod 644 web/sites/default/*settings.php
chmod 644 web/sites/default/*services.yml

4. Post-upgrade tasks

  1. Export configuration: Upgrades often change configuration schema or ordering: drush config:export
  2. Code standards: Run PHP CodeSniffer to align with Drupal 12 coding standards.
  3. Testing:
    • Run automated tests (PHPUnit/Behat).
    • Monitor logs while browsing: drush watchdog:tail
    • Run cron: drush cron

Legacy & appendix

Common issues

  • Dependency resolution failures: If composer update fails, try resetting all constraints: composer show --no-dev --direct --name-only | xargs composer require --no-update
  • Identifying blockers: composer why-not drupal/core ^12
  • Broken patches: If using cweagans/composer-patches, check if patches were merged into core or need updated versions for Drupal 12.
  • Lock file warnings: If the lock file is out of sync, delete composer.lock and the vendor folder, then run composer update.

Support resources

 

Help improve this page

Page status: Needs review

You can: