composer why-not php 8.1. One command, and it tells you who holds you back. Run it before making any plans.

Laravel 10 comes next month and requires PHP 8.1. One project I help with is on Laravel 9 and PHP 8.0. The temptation is one heroic branch: new PHP, new framework, new package versions. When that branch breaks in production, you will not know which of the three changes broke it.

The order that works for me.

First, PHP 8.1 while staying on Laravel 9. Laravel 9 supports it, so this step is legal. Run the test suite on 8.1 in CI next to 8.0. Fix deprecations. Grep for enum used as a class name, it is a keyword now and old generated code sometimes has it. Deploy. Live with it for a week or two.

Second, dependencies. composer outdated -D and go through the list. Every package must declare support for the next framework major before you touch the framework itself. If one does not, you found your real blocker in January, with nothing else in flight.

Third, the framework. By this point the diff is small and boring. Boring is the goal.

New features of Laravel 10 are step four. Upgrade first, deploy, watch the logs. Adopt new toys only on a green stack. A framework upgrade that also changes application behavior is two migrations pretending to be one.

The whole thing is dull. That is the point.

I did the heroic branch once. It was green in CI for a week. Production found the third change on a Sunday.