As of Rector 2.5, Composer-based sets now support Drupal! Instead of manually adding dozens of configuration sets and keeping the list up to date as you upgrade, you enable a single feature in your rector.php.
Rector inspects your composer.json, detects your exact installed Drupal version, and runs the relevant refactoring sets automatically. Upgrade core, run Rector, stay up to date, no manual config changes.
This is a guest post by Björn Brala, a Drupal contributor and maintainer of drupal-rector, who has been working on automated Drupal upgrades.
As of Rector 2.5, Composer-based sets now support Drupal! This allows you to automate version-specific custom code upgrades seamlessly.
Instead of manually adding dozens of configuration sets and keeping your list up to date as you upgrade to new Drupal releases, you can enable the new feature in your rector.php file. Rector will automatically inspect your composer.json, detect your exact installed versions of Drupal and its dependencies, and run the relevant refactoring sets. This means as you upgrade to newer versions of Drupal in the future, Rector will dynamically adapt and apply the correct upgrade rules without any manual config updates.
Install Drupal Rector with Composer:
composer require --dev palantirnet/drupal-rector
That pulls in Rector 2.5 or newer, which is where the interesting part lives. Then create a rector.php in your project root:
<?php
declare(strict_types=1);
use DrupalRector\Set\DrupalSetProvider;
use Rector\Config\RectorConfig;
return RectorConfig::configure()
->withPaths([
__DIR__ . '/web/modules/custom',
__DIR__ . '/web/themes/custom',
// Add paths with code you want upgraded
])
->withSetProviders(DrupalSetProvider::class)
->withComposerBased(drupal: true, twig: true, phpunit: true, symfony: true);
And run it:
vendor/bin/rector process
Two lines of configuration does the work: withSetProviders registers the Drupal rules, and withComposerBased(drupal: true) tells Rector to select them based on what's actually installed. No version numbers need to be in your config.
The feature is backed by recent Drupal Rector 1.0.0 beta releases. Although we are still running a beta for Drupal Rector, the composer-based sets landed in Rector 2.5.0. Run it on your custom code, read the diff, and tell us where it's wrong.
Rector reads the installed drupal/core version and loads every set up to and including that minor. A site on 11.4 loads the 11.0 → 11.4 rules. A site on 11.2 loads 11.0 → 11.2. When you upgrade core, the set selection moves with you. You don't need to change rector.php again.
That's the same mechanism Rector already uses for Symfony, Doctrine, Twig, and PHPUnit. Drupal is now a first-class citizen.
But the config was never the hardest part. The hard part was coverage. Automatic version selection is only worth anything if the rules behind it are good and preferably complete. That changed a lot when the Project Update Bot was refreshed for Drupal 12 readiness, pushing automated deprecation coverage past 80%. The bot and drupal-rector draw from the same well. Better coverage there is what made shipping this as the default setup defensible. The fact we also run all these rules against almost 10.000 contrib modules makes for some very good testing.
Drupal rules will also appear on getrector.com/find-rule at a later date. That's the searchable catalogue of every rule Rector ships. Having Drupal in it means a maintainer can look up exactly which transformation handles a given deprecation, the same way they can for any other framework today.
Drupal 12 readiness isn't a one-time push, every new minor brings deprecations, and we will keep on adding any missing coverage. Because your setup selects rules by installed version, the rules you get tomorrow are the rules for the core you're running tomorrow. No migration step. You upgrade core, you run Rector, you're up-to-date.
Add it to a project this week. Point it at your custom modules, run vendor/bin/rector process, and open an issue when something doesn't transform the way it should. It's a beta because we want exactly that. Two lines of config, the correct rules for your version, automatically.