Upgrading From Laravel 8.x to Laravel 9.x

Laravel 9 was released on 2/8/2022 and in this article, we’ll describe how to update our applications from Laravel 8 to Laravel 9.

If you’re upgrading from a previous version make sure you check out our article on how to upgrade to Laravel 8. You’ll have to upgrade through each version one at a time.

A Disclaimer

Laravel 9 is brand new and because it has breaking changes it has the potential to break our applications so do not install this directly on a production application. We take no responsibility whatsoever for this article breaking anything.

As a general piece of advice, it’s a good idea to hold off a couple of weeks so bugs can get fixed before upgrading any production instances. But it’s okay to install the newest version in a development environment to try out new features and help find any bugs. It’s kind of our duty as developers using open-source software for free.

Support Policy

The Laravel Framework’s Long-Term Support(LTS) releases policy is that bug fixes are provided for 2 years and security fixes are provided for 3 years. Laravel 9 is an LTS release so we’ll get bug fixes until 2025. This makes it a great choice for new projects that might not be maintained all the time but we should upgrade to a newer version before then.

Table with the listing of support dates for Laravel Releases

Upgrade Instructions

Laravel 9’s upgrade path is quite straightforward and all the steps can be found on Laravel’s website at https://laravel.com/docs/9.x/upgrade. It’s important to read the most current version of the upgrade documentation. It changed in the time between when we started writing this post and when we published it.

Check The Changes

Laravel’s upgrade page provides things to look out for lookout for as we’re upgrading. Make sure you read through the changes on the upgrade page to make sure your code isn’t going to be affected. There are a lot of little changes to the code so it’s impossible for us to give specific instructions for everything so make sure you read through everything completely. We didn’t run into any problems but you might.

The biggest change is that, as part of the upgrade to 9, PHP 8.0.2 is now the minimally required version so make sure you’re already running a newer version before continuing. PHP 8.0 and 8.1 both have some great new features so you should get upgraded to 8.1 if you’re not already. You can find information about what’s been added in our “New Features in PHP 8.0 and PHP 8.1” articles.

Create a New Branch

Any time we do a major upgrade, we have to assume it’s a test and we might encounter problems that we can’t get past. Because of this, we may have to abandon this process.

To do that easily, we can create a branch so that we can just delete the branch if something doesn’t work out.

git checkout master
git checkout -b "laravel-9"

Change composer.json

The next thing we’re going to do is open our composer.json and make changes that need to be made to get to version 9.

We have to change.

  • laravel/framework to ^9.0
  • nunomaduro/collision to ^6.0

We’ll end up with something like the following.

    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
    "license": "MIT",
    "require": {
        "php": "^8.0.0",
        "fideloper/proxy": "^4.2",
        "guzzlehttp/guzzle": "^7.0.1",
        "laravel/framework": "^9.0",
        "laravel/tinker": "^2.0",
        "laravel/ui": "^3.0"
    "require-dev": {
        "fzaninotto/faker": "^1.9.1",
        "mockery/mockery": "^1.3.1",
        "nunomaduro/collision": "^6.0",
        "phpunit/phpunit": "^9.0"

Next, we’re going to run composer update.

Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
Package fzaninotto/faker is abandoned, you should avoid using it. No replacement was suggested.
Generating optimized autoload files
Class App\Events\Conference\Event\UpdateWebsite located in ./app/Events/Conference/Event/UpdateWebsite copy 2.php does not comply with psr-4 autoloading standard. Skipping.
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Discovered Package: laravel/ui
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
56 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
$ php composer.phar upgrade
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 18 updates, 4 removals
  - Removing opis/closure (3.6.3)
  - Removing swiftmailer/swiftmailer (v6.3.0)
  - Removing symfony/polyfill-iconv (v1.24.0)
  - Removing symfony/polyfill-php73 (v1.24.0)
  - Upgrading egulias/email-validator (2.1.25 => 3.1.2)
  - Upgrading laravel/framework (v8.83.0 => v9.0.0)
  - Upgrading league/flysystem (1.1.9 => 3.0.3)
  - Upgrading nunomaduro/collision (v5.11.0 => v6.1.0)
  - Upgrading psr/container (1.1.2 => 2.0.2)
  - Upgrading psr/log (2.0.0 => 3.0.0)
  - Upgrading psr/simple-cache (1.0.1 => 3.0.0)
  - Upgrading symfony/console (v5.4.3 => v6.0.3)
  - Upgrading symfony/error-handler (v5.4.3 => v6.0.3)
  - Upgrading symfony/finder (v5.4.3 => v6.0.3)
  - Upgrading symfony/http-foundation (v5.4.3 => v6.0.3)
  - Upgrading symfony/http-kernel (v5.4.4 => v6.0.4)
  - Locking symfony/mailer (v6.0.3)
  - Upgrading symfony/mime (v5.4.3 => v6.0.3)
  - Upgrading symfony/process (v5.4.3 => v6.0.3)
  - Upgrading symfony/routing (v5.4.3 => v6.0.3)
  - Upgrading symfony/service-contracts (v2.4.1 => v3.0.0)
  - Upgrading symfony/var-dumper (v5.4.3 => v6.0.3)
  - Upgrading voku/portable-ascii (1.6.1 => 2.0.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 18 updates, 4 removals
  - Downloading laravel/framework (v9.0.0)
  - Downloading nunomaduro/collision (v6.1.0)
  - Removing symfony/polyfill-php73 (v1.24.0)
  - Removing symfony/polyfill-iconv (v1.24.0)
  - Removing swiftmailer/swiftmailer (v6.3.0)
  - Removing opis/closure (3.6.3)
  - Upgrading voku/portable-ascii (1.6.1 => 2.0.0): Extracting archive
  - Upgrading symfony/var-dumper (v5.4.3 => v6.0.3): Extracting archive
  - Upgrading symfony/routing (v5.4.3 => v6.0.3): Extracting archive
  - Upgrading symfony/process (v5.4.3 => v6.0.3): Extracting archive
  - Upgrading symfony/mime (v5.4.3 => v6.0.3): Extracting archive
  - Upgrading psr/container (1.1.2 => 2.0.2): Extracting archive
  - Upgrading symfony/service-contracts (v2.4.1 => v3.0.0): Extracting archive
  - Upgrading psr/log (2.0.0 => 3.0.0): Extracting archive
  - Upgrading egulias/email-validator (2.1.25 => 3.1.2): Extracting archive
  - Installing symfony/mailer (v6.0.3): Extracting archive
  - Upgrading symfony/http-foundation (v5.4.3 => v6.0.3): Extracting archive
  - Upgrading symfony/error-handler (v5.4.3 => v6.0.3): Extracting archive
  - Upgrading symfony/http-kernel (v5.4.4 => v6.0.4): Extracting archive
  - Upgrading symfony/finder (v5.4.3 => v6.0.3): Extracting archive
  - Upgrading symfony/console (v5.4.3 => v6.0.3): Extracting archive
  - Upgrading psr/simple-cache (1.0.1 => 3.0.0): Extracting archive
  - Upgrading league/flysystem (1.1.9 => 3.0.3): Extracting archive
  - Upgrading laravel/framework (v8.83.0 => v9.0.0): Extracting archive
  - Upgrading nunomaduro/collision (v5.11.0 => v6.1.0): Extracting archive
Package fzaninotto/faker is abandoned, you should avoid using it. No replacement was suggested.
Generating optimized autoload files

Now that everything has been downloaded successfully we want to make sure we commit composer.json and composer.lock to our repository.

Next, we’ll run our tests and check critical pages and make sure that nothing broke.

Once we feel confident that it’s working we can merge the branch into master

git checkout master
git merge "laravel-9"


If you run into problems with this upgrade we always suggest restarting and trying again. Then check the upgrade notes and make sure nothing changed that you’re dependent on.

If that doesn’t work might be time to try Laravel Shift which can automatically upgrade a Laravel 8 application to Laravel 9.

Enjoy The Upgrade

Hopefully, the upgrade has gone smoothly and our application is now up to date with Laravel 9.