Drupal Rector for automated deprecation fixes

Drupal Rector applies automated fixes to the deprecated API uses that Upgrade Status reports, which cuts upgrade effort on custom modules and themes. The remaining findings still need developer review and testing.

On this page

How Drupal Rector cuts deprecation work before a Drupal 12 upgrade

Drupal Rector fixes the deprecated API uses that Upgrade Status reports where a fix is available, and everything else still needs a developer. For a team with custom modules and themes that must move to the next major version, the first step is to run Upgrade Status on the current site against the next major version. Upgrade Status finds the deprecated calls, suggests the drupal-rector command line tool where it applies, and sorts each result into Rector fixable or manual review. The Rector fixable group is where the effort reduction comes from, and the manual review group is where the planning time goes. Run the check on the code you own, not on a copy with local edits that nobody can reproduce later.

The timing comes from the Drupal core release schedule. Drupal 11 is the current major version, Drupal 12 is scheduled for the week of December 7, 2026, and Drupal 10 reaches end of life on December 9, 2026. A team on Drupal 10 that waits for Drupal 12 to ship has very little time left on its current version, so the Upgrade Status run belongs in the current planning cycle, not the release week. Confirm the Drupal 11 minor release you will target and the PHP version your hosting provides, because Drupal 12 requires PHP 8.5 or later and that check can block the code work entirely. Ask your team to list which custom modules and themes have the most findings before deciding the sequence.

Rector is one step in the supported path, not a full upgrade. Its changes are automated rewrites of code, so every changed file needs a review in version control, a run of the site's automated tests, and a check of the behavior that the tests do not cover, such as forms, permissions and custom entity handling. Contributed modules must also have a release compatible with the target version, and Upgrade Status reports that separately. Plan for Rector to shorten the mechanical part of the work while the manual review group, the contributed module readiness check and the testing set the actual duration. Ask any partner to show the Upgrade Status report for your code and to separate the Rector fixable items from the manual items in the quote.

What changes for custom code and the platform, and what to do about it

This table compares the platform, code and release changes that affect a Drupal Rector upgrade, with the impact of each and the action your team needs to take. Read it row by row before scoping, because the PHP requirement and contributed module readiness can block work that Rector cannot touch.

ChangeImpactAction needed
PHP 8.5 requirement for Drupal 12Drupal 12 requires PHP 8.5 or later, while Drupal 11 requires PHP 8.3 or later, so server upgrades gate the code upgrade.Confirm current PHP version on all environments and plan the server upgrade before running Rector changes.
Deprecated API uses that Rector fixesUpgrade Status reports these uses and suggests drupal-rector, which can apply mechanical changes to custom code.Run Rector on a branch, review the diff, and commit the changes in reviewable batches.
Deprecated API uses for manual reviewResults flagged for manual review need developer judgment because the change is not mechanical.Assign each item to a developer, fix it, and re-run Upgrade Status until the report is clean for custom code.
Contributed modules without a compatible releaseCustom code cannot pass checks cleanly if a contributed dependency has no release for the target version.Check each contributed project on Drupal.org, plan replacements or patches, and record the decision.
Release cadence on Drupal.orgBugfix releases come out on the first Wednesday of each month and security releases on the third Wednesday, so test windows recur.Schedule upgrade work around these dates and keep a routine for applying security releases during the project.

What to back up and inventory before running Rector

Drupal Rector rewrites code in place, so the work only stays safe if you can restore the site and see exactly what changed. These six items give you a rollback point, a scope, a baseline and a review path before the first automated change is made.

Full database and codebase backup

Take a complete database dump and confirm the codebase, including custom modules, themes, composer.json and composer.lock, is committed to version control before any Rector run. A backup you have not restored is not a rollback plan, so restore it to a scratch environment and confirm the site boots. Keep the dump and the commit hash together so you can return to an exact state.

Inventory of custom code and owners

List every custom module and theme, the path it lives in and the named team or person who approves changes to it. Rector will touch code you did not expect, so owners need to know which files are in scope and who reviews their diffs. Include custom code inside custom directories and any patched contributed projects, since those are easy to miss.

Upgrade Status baseline report

Run Upgrade Status against the current site for the target major version and save the full report as a dated baseline. Upgrade Status finds deprecated API uses but cannot fix them, and it labels each result as Rector fixable or manual review. The saved baseline lets you measure what Rector removed after each run and prove that no new findings were introduced.

Test environment matching production

Build a non-production environment that runs the same PHP version and database engine and version as production. Rector output and test results are only meaningful when the runtime matches, so check the PHP minimum for your target version against your current stack. Confirm your web server, database and PHP settings in the test copy before running any automated change.

Clean working tree and change branch

Start from a clean working tree on a dedicated branch so uncommitted local edits do not mix with Rector changes. Commit each Rector run as its own change set, and review each one as a diff before the next run. Small, separate commits make a regression traceable to one rule set and easy to revert.

Contributed module compatibility list

List every contributed module and theme with its installed version, the release that supports the target major version, and its maintainer status. Rector can fix deprecated calls inside contributed code, but a project without a compatible release blocks the upgrade regardless of what Rector does. Record which modules need replacing, patching or upstream updates so that these decisions are made before the automated changes begin.

How to run Rector fixes and reviews in order

This sequence moves custom Drupal code from deprecated API use to a reviewed, tested state in small batches. Each batch ends with a tagged commit and a restorable backup, so any change can be reversed without losing the work already reviewed.

  1. Confirm PHP and hosting requirements for the target version

    Before any code changes, the team confirms that the target Drupal version's PHP and database requirements are met in the staging environment. Drupal 11 requires PHP 8.3 or later, and Drupal 12 requires PHP 8.5 or later, so the platform team should check the runtime version and the database version against the Drupal.org system requirements. The step is done when a staging site on the target PHP version boots the current codebase and passes a basic smoke test. If the requirements are not met, the server upgrade is scheduled first, because Rector results on an unsupported runtime cannot be trusted. Rollback: no code has changed yet, so the only rollback is reverting the staging server runtime to its prior version.

  2. Run Upgrade Status on the current site

    The developer lead installs Upgrade Status on a copy of the current site and runs it against the next major version, because the checks must run on the live codebase with the target version in mind. The report lists deprecated API uses and separates findings that Rector can fix from findings that need manual review. The step is done when the report is saved as a baseline with a count of findings per custom module and theme. Rollback: running the report changes nothing, so no rollback is needed beyond discarding the staging copy.

  3. Run drupal-rector on custom code in a branch

    A developer creates a feature branch from the main branch and runs drupal-rector only against custom modules and themes, not contributed projects or core. Each change is applied as a diff, and the developer reviews every changed file against the Upgrade Status finding it addresses before accepting it. The step is done when the branch contains only changes that match a finding in the baseline report. Rollback: the branch is discarded or reset to the commit before Rector ran, so the main branch is never touched at this stage.

  4. Commit fixes in reviewable batches

    The developer groups the accepted Rector changes into small commits, for example one commit per custom module or per deprecated API, so that a reviewer can read each batch on its own. Each commit message names the Upgrade Status finding it resolves. The step is done when every batch has passed code review and the branch builds on the staging site. After each approved batch, the team creates a tagged commit and takes a database and file backup of the staging environment, so there is a known restore point. Rollback: revert the batch commit or restore the tagged state and its backup.

  5. Handle manual review items

    Findings that Rector cannot fix, such as changed method signatures, altered hook behavior or removed APIs without a direct replacement, are assigned to a named developer with a ticket that links to the Upgrade Status line. The developer rewrites the affected code by hand, and a second developer reviews it. The step is done when every manual item is closed or explicitly accepted as a known risk with an owner. Rollback: each manual fix is its own commit, so it can be reverted independently of the automated batches.

  6. Re-run Upgrade Status

    After all batches and manual fixes are merged into the branch, the developer runs Upgrade Status again on the same target version and compares the new report against the baseline. The expected result is that every Rector-fixable finding is gone and the remaining findings are only those accepted in the manual review step. The step is done when the comparison is attached to the change record. If new findings appear, they are treated as regressions and fixed before moving on. Rollback: return to the last tagged batch and repeat the affected part of the sequence.

  7. Run automated and functional tests

    The QA lead runs the project's automated test suite, PHPUnit and any kernel or functional tests the custom code already has, along with a scripted walkthrough of critical user journeys on the staging site. Failures are triaged to the batch that introduced them. The step is done when the agreed test set passes on the target PHP version and the walkthrough has been signed off by the business owner. Where the custom code has little test coverage, the team should confirm with the client what manual test scope is acceptable before sign-off. Rollback: failing batches are reverted to their tagged commit and re-reviewed before testing resumes.

  8. Define a rollback point after each batch

    Every approved batch closes with a named Git tag and a verified backup that can be restored to a clean environment. The operations lead confirms that the backup restores the database and the file system together, and that the tag builds from a clean checkout. The step is done when the rollback procedure has been rehearsed on a non-production copy and the tag, backup location and restore steps are recorded in the change log. Rollback: the restore procedure itself is the rollback, and it should be tested before any production change is scheduled.

Which findings Rector fixes and which need a developer

Upgrade Status categorizes some findings as Rector fixable and suggests the drupal-rector command line tool for them. Rector rewrites deprecated API calls in custom code into their documented replacements, which removes repetitive edits across many files. Rector is a mechanical tool, though, so the output still needs review before it is merged. The reviewer's job is to confirm that the rewritten code does what the original did, not only that it now uses a current function name.

  • Renamed or moved calls: Check that the new call receives the same arguments in the same order and returns the same type the surrounding code expects.
  • Changed defaults: Look for rewrites that add or drop optional parameters, since a changed default can alter query results or cache behavior.
  • Dependency injection changes: Confirm that services Rector injects or replaces are available where the class is instantiated, including in tests.
  • Formatting noise: Separate whitespace and reordering changes from functional changes so the diff stays reviewable.
  • Tests: Run the custom module test suite and a functional smoke test on the changed paths, because Rector cannot judge whether a behavior change is intended.

Before approving a Rector commit, confirm that each changed file is covered by a test or a manual check on the affected page or workflow.

What makes Rector-assisted upgrades take longer

This table lists the drivers that change how long a Rector-assisted upgrade takes and what each one asks you to check before committing to a plan. Use it to size the work on your own codebase, since none of these drivers has a fixed duration. The main takeaway is that the share of findings needing manual review and the state of contributed modules usually matter more than the raw count of deprecations.

DriverEffect on effortWhat to check
Volume and spread of custom codeMore modules and themes multiply the findings to review and the test runs needed after each change.Count custom modules, themes and custom entity types, and how many depend on each other.
Share of findings in manual reviewRector fixes mechanical changes, while manual findings need a developer to read the code and decide the change.Compare the Rector fixable and manual review counts Upgrade Status reports for each project.
Contributed modules without a compatible releaseCustom code that depends on a module with no release for the target version may need replacing or waiting.Check each contributed project's release list for the target major version before fixing code.
Undocumented custom APIs and missing testsWithout documentation or tests, developers cannot confirm that a Rector change preserved behavior, so review slows down.Identify custom services, hooks and plugins with no tests, and whether any owner can explain their intent.
Number of Drupal versions being crossedEach major version adds a separate set of deprecations, and a site on an older version needs intermediate steps first.Confirm the current version and the path to the target, since Upgrade Status checks run against the next major version.
PHP and database upgrades needed firstServer changes gate the code work, so a PHP or database gap can block Rector runs and testing.Compare the current PHP version and database with the target version's requirements on Drupal.org before starting.
Team review capacityRector output is a set of proposed diffs, and the review queue grows faster than the fixes if few people can approve changes.Confirm who reviews generated changes, how many reviewers are available, and how changes are batched and merged.

How to test Rector changes and roll them back safely

Verify every Rector change set before it reaches a shared environment, and treat the Rector diff as the primary review artifact. Run the custom module and theme test suites first, wherever they exist, because a passing PHPUnit or Kernel test run is the cheapest signal that a rewritten call still behaves the same. Where a custom module has no tests, say so in the change record, since that gap determines how much manual checking the batch needs. Then read the diff line by line for behavior changes that tests rarely catch, such as altered default arguments, changed return types, or a rewritten hook that now runs in a different order. Confirm with your own developers which fixes are mechanical and which were flagged for manual review, and keep the manual items in a separate commit.

Functional checks should follow the business paths the batch could touch: content types and their field widgets, forms and their validation, user roles and permission-gated pages, and the integrations that exchange data with the site. Add visual checks on the custom themes, comparing key templates and components before and after the change, because Rector rewrites PHP and does not judge rendered output. Use a staging copy built from a recent sanitized database so these checks run against realistic configuration. Record which checks passed, who ran them, and the commit they covered.

Plan rollback before the first change set is applied. Tag the commit at the end of each batch so a bad change can be reverted cleanly, and keep the contributed module set pinned in composer.lock so a rollback restores the same dependency versions. If a batch touched data or configuration, restore the pre-change database backup rather than attempting to reverse configuration by hand, and confirm that the backup restores into a test environment before you rely on it. Create a rollback point after each batch, not only at the start of the project, so that a fault found three batches later can be isolated to one set of changes. Confirm your backup retention and restore timing with your own operations team, since those figures depend on your infrastructure.

How much effort does Rector-assisted upgrade work take, and what does it need from our team?

What drives the cost and effort of Rector-assisted upgrade work?

The main drivers are the volume of custom code, the share of Upgrade Status findings that need manual review, the readiness of each contributed module, and how much automated test coverage exists to confirm behavior after changes. Rector handles the mechanical part for findings it can fix, so a codebase with many fixable findings and little manual work costs less to clear than one dominated by hand-rewritten logic. Ask any provider to split the quote into the audit, the Rector pass, manual remediation, contributed module decisions and testing, since those are the parts that scale differently. Costs for the upgrade work are one-time, while the code you leave behind is a recurring maintenance cost if it stays on deprecated APIs.

Can our own developers run drupal-rector without outside help?

Yes, for the findings Upgrade Status marks as Rector fixable, your developers can run the drupal-rector tool themselves, provided someone reviews each change before it merges. The tool rewrites deprecated calls mechanically, so the review should confirm that the new code keeps the original behavior and passes the existing tests. Findings categorized for manual review are different: they need developers who know the custom code well enough to decide how the logic should change, and they often involve design choices rather than a find-and-replace. If your team lacks that knowledge for a specific module, that module is where outside help adds the most value.

What does the upgrade work need from our team?

The work needs access to the code repository and a current copy of the site configuration, a named owner for each custom module and theme who can answer questions about intended behavior, and a test environment that matches production closely enough to catch regressions. It also needs decision makers who can approve replacing or dropping contributed modules that lack a release for the next major version, because those choices affect features and budget. Plan for someone to review and approve each Rector change in version control. Confirm these inputs in writing before work starts, because missing owners or test environments are a common reason fixable findings take longer than expected.

How long does a Rector-assisted upgrade take?

Duration depends on the same drivers as cost: the amount of custom code, the number of manual findings, how many contributed modules need replacement, and how fast your team can review and approve changes. Timing is also set by the Drupal release calendar. Bugfix releases come out on the first Wednesday of each month and security releases on the third Wednesday, and Drupal 12 is scheduled for the week of December 7, 2026, while Drupal 10 reaches end of life on December 9, 2026. Ask for a timeline built from your own audit results rather than a generic estimate, and check it against those dates in the Drupal core release schedule.

Does Rector replace the whole Drupal upgrade?

No. Rector covers deprecated API use in custom code, and only the subset of that work with a known automated transformation. It does not upgrade contributed modules, change the PHP version, update the database, rebuild themes that depend on removed components, or validate business behavior. Those tasks remain part of the upgrade plan, and some of them, such as checking that a contributed module has a compatible release, can block the whole project regardless of how many findings Rector clears. Treat Rector as one reduction in the custom-code workload inside a larger upgrade plan.

What should we ask for in a written scope for this work?

A written scope should list the Drupal versions in and out of scope, the modules and themes covered, and the audit results used as the baseline. It should state how many findings are expected to be Rector fixable versus manual review, based on the audit, and who reviews and approves each automated change. Ask the provider to define the testing approach, the acceptance criteria, the handling of contributed modules without a compatible release, and what happens when new findings appear during the work. Also confirm deliverables such as a change log, a remaining-findings report and handover documentation, and whether ongoing support is a separate retainer.

How DeployOpen scopes, runs and supports a Rector-assisted upgrade

DeployOpen plans Drupal Rector work as part of a written, fixed-scope engagement inside your own infrastructure. We use Upgrade Status findings to decide which deprecated API uses Rector can fix, then review every automated change and document the manual work that remains.

How we scope

  • The written scope lists which custom modules and themes Rector will process, and which Upgrade Status categories are in or out.
  • We record the Upgrade Status report against the current site and the target major version before any code changes start.
  • Manual review items, contributed modules without a compatible release and core removals are listed as separate scope lines with owners.

How we build

  • We run drupal-rector on a branch of the custom code, so each automated change is reviewed as a normal pull request.
  • Rector output is checked against the Upgrade Status report again, and any findings it does not clear are handled by hand.
  • Automated and manual changes are tested in a staging environment that mirrors your production hosting and configuration.

How we hand over

  • You receive the Rector configuration, the commit history of automated changes and a list of manual fixes with their reasons.
  • The handover document records the remaining deprecations, the test results and the contributed modules still awaiting an update.
  • Your team walks through the review notes so future Rector runs can be repeated by your own developers.

How we support

  • Ongoing support, upgrades and continuous testing are available as a retainer, which can cover later Drupal minor and major releases.
  • Retainer scope, response expectations and cadence are agreed in writing, so you can confirm them against your own change control.
  • Questions about the Drupal 12 timeline should be checked against the Drupal core release schedule before the work is planned.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.