Shift with red gradient lettering

Upgrading old Laravel applications

Speed up the upgrade process even more with tips from the creator of Shift.

Watch Next

Maintaining Shiftability

Tips on how to keep your project upgradable.

Staying up-to-date forever

Subscribe to a Shifty Plan to stay up-to-date and access additional automation tools.

Dealing with Dependencies

How to resolve composer package incompatibilities.


While Shift will definitely speed up the process of upgrading, as the creator of Shift, I have some tips that will make the process even faster.

So if you're running an old Laravel application or need to run multiple Shifts, you'll definitely want to watch this video. Maybe even twice.

The first thing I like to do is to create an upgrade branch. Even though all shifts create a separate branch, I like creating this extra layer of separations since I plan to upgrade multiple versions at once.

Next, if this is an old Laravel application, I like to check for any outdated practices.

The most common one is a custom app namespace. This was common in earlier versions of Laravel, but no longer recommended.

In fact the Artisan command to do so has been removed. So it's best to go ahead and change this back to the default App namespace while this command is still available.

In addition, some older applications had code outside of the app folder. If so, you may wish to consolidate this under the app folder for a more default structure. This will also improve Shift's automation.

If you do not wish to consolidate these folders, you may configure Shift to review the code within these additional paths.

Finally, one of the largest headaches with any upgrade will be the dependencies. While Shift does it's best to bump the constraints for core dependencies as well as popular packages, it's good to check the upgrade path for your dependencies. For very old Laravel applications, particularly to see if they've been abandoned.

Although abandoned packages should not prevent you from upgrading, it's good to know which ones are. This way you can safely ignore any changes related to that code during the upgrade.

To help check for package compatibility, Shift offers a tool to answer the question, Can I Upgrade Laravel. Any packages which are listed as incompatible or untracked you should review.

You may do so by checking the package source. If necessary, review their composer.json file to ensure compatibility.

Now that we've done some prep work we're ready to begin Shifting. This project is currently running Laravel 5.1. So I want to run the Shifts incrementally starting with the Laravel 5.2.

For old Laravel applications, I tend to run the shifts between the LTS versions very quickly. Only reviewing the comments for critical changes.

Once I reach and LTS version, in this case Laravel 5.5, I'll slow down and smoke test the application to get a feel for how it's going.

So let's see this in action by running the Laravel 5.2 Shift. I'll enter the repository details, running against the laravel-upgrade branch, and complete the checkout to run Shift.

First things first, let's checkout the branch Shift created.

Now, when I'm reviewing the PR‘s for the versions in between the Laravel LTS releases, I can be more strategic with my changes.

Since my ultimate goal is to upgrade to the latest LTS release or latest stable release, I don't really care about the changes in these releases.

So when I encounter comments that shift suggest comparing my files to the core file, I simply copy the core file and overwrite my own.

This guarantees that future changes will be automated by Shift. Then, after I run my final Shift, I can reapply my customizations once at the end, instead of carrying them between each Shift.

I also like to make these changes in an atomic commit. That way I can save a reference to the commit to make things easier to review later.

For any changes I do make, I go ahead and remove the comment. This helps streamline the PR to only the comments I care about.

I'll continue to review this Shift pretty quickly for additional comments. If I know something doesn't pertain to this application I'll immediately remove it. If it does I'll leave a comment or a reaction to make sure I come back and look at it later.

Again, I want to give this a quick review. At this point, I really only care about the error comments. These are the only comments that need to be address now and will improve future automation.

So I'll continue to default files, or make quick updates. For example, if there is an outdated dependency, I can remove it. Or if I know a dependency has been replaced, like illuminate/html, I'll go ahead and replace it.

Once I've gone through all the comments, I'll go ahead and merge this into the laravel-upgrade branch. While I sometimes squash merge my PRs, I don't like to do so in this case.

That's because I want to keep the atomic commits so they're easier to reference later. When I'm done and have verified the upgrade, I may instead squash merge the PR for the laravel-upgrade branch.

Okay, let's carry on by running the Laravel 5.3 Shift. I may do this quickly from the Shift dashboard.

I'll follow the same process of quickly reviewing the comments and only addressing the critical ones.

Again, any files which need defaulting or code which is no longer valid. Then I'll immediately merge this. I'll continue this for each Shift until I reach an LTS release. In this case, Laravel 5.5.

Ok. Once on an LTS release, I'll slow down a bit. I'm not stopping on Laravel 5.5. It's still an outdated version. So I want to continue the practice of defaulting files to improve the automation of future Shifts.

It also looks like the bootstrapping changed. So I'll quickly search the project for any instances of this path to ensure the application wasn't using this file directly. Seems okay, so I'll remove this comment.

Moving along, I may want to address some of these comments later, so I'll leave a reaction to remind me to take a look.

The next comment is a core dependency mismatch. So I'll quickly change that in composer.json.

Alright, I've already looked at the bootstrap file, so I can ignore the next comment.

There's a few more informational comments I may want to review once I'm done upgrading. So again, I'll leave a reaction to remind me.

I'll continue this process or addressing critical comments, removing inapplicable comments, and deferring comments with reactions until I've reviewed all the PR comments.

I'll review the changes I made and make those atomic commits so they're easier for me to review later.

Now, since I'm on an LTS release, I want to “smoke test” the application. This is simply a combination of running composer update to check the dependencies and artisan to ensure the application can at least load the core framework components.

It's pretty likely at this point I'll have some dependency issues. So I will take a minute to work through them by getting composer update to run.

First, looks like had a direct dependency for this exceptions package. However, it no longer references it since I'm leveraging Laravel's built-in exception handling. So I want to remove any dependency that is no longer used.

Running composer again seems like everything is still compatible. But if you get stuck on this step, there's a separate video for Dealing with Composer dependencies demonstrating even more tricks.

Remember, at this point, I'm only checking for compatibility. These packages may have additional upgrade steps which I'll need to review later.

But since I don't know if all these packages are fully compatible with the latest Laravel release, I don't want to spend too much time now.

Again, my goal is to only make the changes I need and let Shift do the upgrade work. Then I'll refactor at the end.

Now that composer runs, I'm going to attempt to run php artisan. This serves as a way to boot the framework and ensure the application loads.

Looks like there's an error with one of the service providers. I actually removed this package in a previous Shift. So I'll go ahead and unregister it.

Running artisan again, I get a similar error. Now, as the creator of Shift, I know this share() method has to do with some old code. So I want to check this package to ensure it is still compatible.

Looking at the repository on GitHub, it appears this should be compatible all the way up to Laravel 5.7. It's likely composer is just loading an older version.

So I'll copy their install script and run it again to get the latest version of the package. Looks like that bumped it, and running artisan again outputs the full command list as expected.

So let's commit these latest changes. And now that the smoke test is passing, I'll merge the PR.

Then I'll repeat the process and move quickly to the next LTS version.

In this case I'll run the Laravel 5.6, 5.7, and 5.8 Shifts. Then I'll run the Laravel 6.x Shift which is another LTS release. Since that is the latest LTS release, I'll slow down there.

Okay, so I've continued the process of running the Shifts and reached Laravel 6. Scrolling through the PR comments, notice at this point all of the comments are informational.

Because I've followed this process, Shift is automating a majority of the changes.

There's really nothing I need to do with this PR. So let's do another smoke test.

I'll start by running composer. Right away I notice an incompatibility. It's that same shopping cart package from earlier. This was expected since the last commit noted support for Laravel 5.7 nearly 2 years ago.

However, since this is a popular package, it's worth reviewing the open PRs to see if someone submitted the changes for Laravel 6 or higher. Fortunately, it looks like there are several. I can review them to see which one appears to be the most thorough. This one has the most activity, so I'll try it.

To do so, I'll copy the URL to the fork and configure composer to pull this package from the fork.

I also need to update the constraint to reference the branch that has these updates. In this case, they're on the master branch, so I'll enter dev-master.

Running composer again, looks like that worked, but I have another package that is incompatible.

I know this is compatible from using Can I Upgrade Laravel earlier, so I'll simply reinstall it to bump the dependency.

Running composer again, looks like I'm past the incompatibilities. Again, this a majority of the work when upgrading. And I should still check if these packages I've bumped have any additional changes I need to make.

Now that composer is running, I'll run php artisan. And it's all good.

Since this smoke test passed without much effort, and I know the remaining packages are compatible, I would continue shifting on to the latest version of Laravel.

However, if there was an issue during the smoke test, I'll likely stop and resolve these errors to ensure the application can run. If so, it's likely that the application will also run on the latest version so those shifts will be a lot easier.

Whichever release you decide to stop on, the next step will be reviewing the files I defaulted. Since I know these files are fully upgraded, I may simply reapply any customizations.

Most of the time you'll realize the changes are not necessary. They're simply whitespace, simple name changes, or unmodified code.

When I do find a customizations, I simply copy the code back and take the opportunity to refactor it with any modernizations in the framework.

Once I review all the customizations, I'd spend some time reviewing the application and running any tests.

While you're welcome to stay on an LTS version, Shift of course encourages you to run the latest version so you have access to all the newest features and to keep the upgrade process smooth.

With that said, Shifts for recent versions do a better job of maintaining your customizations as well as automating the process of bumping your Composer dependencies.

So once you are on the recent LTS version or higher, you may follow the normal review process when running Shift.

And once you are on the latest version you may run the Upgrade Checker to search for any outdated code within your application

Or the Laravel Fixer to automate the process of refactoring your code to use modern Laravel conventions.

Sign in with any of the following services to connect Shift with your Laravel project.

Don't use one of these services?

Temporarily push your project to a free, private repository on one of these cloud-based services or upgrade your project locally with Shift for Docker.