
The Drupal 9 to Drupal 10 upgrade was structurally different from the Drupal 7 to Drupal 9 transition. Drupal 9 to 10 was a normal version upgrade with a finite set of prerequisites and deprecation cleanups. Drupal 7 to 9 had been effectively a re-platform. For institutions that had already completed the harder migration, Drupal 10 was a manageable upgrade that could be planned and executed in a single project cycle.
This is the checklist of what institutions actually had to plan for in a Drupal 10 upgrade. It is written from the operational perspective of agencies and universities running Drupal in production with FedRAMP, NIST 800-53, FERPA, or HECVAT compliance constraints.
Prerequisites: PHP, Composer, and Drupal 9.5
Drupal 10 requires PHP 8.1 or higher. Institutions running PHP 7.4 or 8.0 had to upgrade the PHP runtime before the Drupal upgrade could proceed. For most production environments, this meant a coordinated change to the EC2 AMI, container image, or platform PHP version, with regression testing of the application against the new runtime.
Composer 2.3.6 or higher was required. Composer 1.x was no longer supported. For institutions using older deployment automation, this was the moment to update CI pipelines.
Drupal 10's upgrade path expects the source site to be on Drupal 9.5. Older versions of Drupal 9 had to be brought current first. This was a quick upgrade in itself but had to be planned as a separate step.
Deprecation Cleanup Through Upgrade Status
The single most useful tool in the upgrade was the Upgrade Status module. Run against a Drupal 9.5 site, it produces a detailed report of:
- Modules removed from Drupal 10 core (
color,seven,bartik,classythemes,quickedit, etc.) - Modules with no Drupal 10 release available
- Custom code calling deprecated APIs that will be removed in 10
- info.yml and composer.json fields that need updating
The output is the work plan. Each item either has an obvious fix (replace removed modules with their new equivalents, update API calls), a planned fix (port custom modules to Drupal 10 compatibility), or a decision (replace functionality that no longer exists in core).
For a moderately complex institutional site, the deprecation cleanup was typically two to four weeks of focused work.
Theme Migration to CKEditor 5 and Olivero
Drupal 10 replaced CKEditor 4 with CKEditor 5 as the default rich-text editor. CKEditor 4 reached end of life in mid-2023 and was removed from Drupal 10 entirely.
For institutions with custom CKEditor configurations (custom toolbars, plugins, validators), the migration was the most involved part of the upgrade. CKEditor 5 has a different API surface and a different plugin model. Configuration was not automatically migrated, and several common CKEditor 4 plugins did not have direct CKEditor 5 equivalents.
Drupal 10 also introduced Olivero as the default front-end theme, replacing Bartik. Institutions running custom themes did not have to switch to Olivero, but the default front-end of any new Drupal 10 installation looked different. The Claro admin theme (introduced in Drupal 9) became the default admin experience.
Contributed Module Compatibility
Most actively-maintained contributed modules had Drupal 10 releases by mid-2023. Less actively maintained modules sometimes did not. The decision for each was binary: upgrade the module to a Drupal 10 release if available, or replace it with an alternative.
For institutional sites with twenty or more contributed modules, this was where a Drupal 10 upgrade timeline could stretch unexpectedly. A single module without a Drupal 10 release that was load-bearing for the institution's content workflow could block the entire upgrade until either the module was forked and ported, or its functionality was rebuilt.
Drush 11
Drupal 10 required Drush 11 for command-line operations. Earlier versions of Drush did not work with Drupal 10. For institutions using Drush in CI/CD pipelines, this was a coordinated change to the deployment automation.
Database Compatibility
Drupal 10 supports MySQL 5.7.8+, MariaDB 10.3.7+, PostgreSQL 12+, and SQLite 3.26+. Most institutional environments running RDS were already on supported versions, but institutions with older PostgreSQL or MySQL deployments had to plan database engine upgrades alongside the Drupal upgrade.
For managed Drupal hosting for government, the database tier was typically already current because of the routine patching discipline of public-sector hosting environments. For institutions self-managing their database tier, this could be an unexpected scope expansion.
The Operational Sequence
The upgrade pattern that worked reliably across institutions:
- Run Upgrade Status against the production Drupal 9.5 site. Capture the deprecation report.
- In a non-production environment, upgrade the PHP runtime to 8.1+.
- Update Composer to 2.3.6+ and update CI/CD scripts.
- Apply deprecation fixes to core, contributed modules, and custom code.
- Replace removed modules with their Drupal 10 alternatives. Test functionality.
- Migrate CKEditor configurations to CKEditor 5. Test the editorial experience.
- Run the actual Drupal 10 core update in the non-production environment.
- Run regression tests. Fix any issues. Re-run.
- Schedule a maintenance window for production. Apply the upgrade against production with the same procedure.
- Validate against the institutional acceptance criteria.
For institutional sites with mature deployment automation and a well-curated module list, this entire sequence was four to eight weeks of work. For sites with substantial custom code or a long-tail of contributed modules, it could be three to six months.
Compliance Considerations
For agencies under FedRAMP, NIST 800-53, or other security review cycles, the Drupal 10 upgrade affected several compliance controls:
- The PHP runtime upgrade was a system-level change requiring documentation and possibly a security impact analysis
- The CKEditor 5 migration affected the input validation and output sanitization paths, which were typically called out in security control documentation
- Module changes affected the system's authorization boundary, which had to be re-documented
- The upgrade itself was a configuration change requiring change management approval
Institutions that planned the upgrade with these compliance dimensions in mind avoided the situation where the technical work was complete but the documentation work to close out the change took another month.
Frequently Asked Questions
How long does a Drupal 9 to Drupal 10 upgrade typically take?
For a moderately complex institutional site with mature deployment automation, four to eight weeks. For sites with substantial custom code, twenty or more contributed modules, or significant CKEditor customization, three to six months. The variability is mostly driven by deprecation cleanup and module compatibility, not by the core upgrade itself.
Do we have to upgrade to Drupal 10 immediately?
Drupal 9 reached end of life on November 1, 2023. After that date, security advisories were no longer published for Drupal 9. Institutions running Drupal 9 in production after the EOL had the same operational exposure as institutions running post-EOL Drupal 7: vulnerabilities could not be patched through the standard release process.
Can we skip Drupal 10 and go directly to Drupal 11?
Drupal's upgrade policy supports skipping minor versions but typically not major versions. The stable upgrade path is 9 to 10 to 11. The work to upgrade from 9 to 11 directly is similar to 9 to 10 to 11 sequentially, and the sequential path has more documentation.
What is the relationship between the Drupal upgrade and the production hosting environment?
The Drupal upgrade is an application-tier change. The production hosting environment (operating system, PHP runtime, web server, database engine, network and security configuration) often needs coordinated changes to support the new Drupal version. For managed Drupal hosting for government, we typically schedule infrastructure preparation as part of the upgrade plan rather than treating it as a separate project.