How to Upgrade Laravel 11 to Laravel 12: Complete Step-by-Step Process

Overview

Upgrading from Laravel 11 to 12 is designed to be quick — the official documentation estimates just 5 minutes for most applications. However, to ensure no breaking changes affect your project, it's crucial to follow a structured approach. We'll walk you through the entire process step by step, including complete code examples, handling potential issues, and best practices. Whether you're maintaining a small blog or a large-scale enterprise application, this tutorial will help you transition smoothly while minimizing downtime.

Why upgrade? Laravel 12 offers better compatibility with the latest PHP versions, refined concurrency handling, and minimal breaking changes, allowing you to benefit from bug fixes and security patches until February 2027. Plus, the new starter kits with WorkOS AuthKit streamline full-stack development, making it easier to scaffold projects with popular frontend tools. If your app is already on Laravel 11 and PHP 8.2 or higher, you're in a prime position for this upgrade.



How to Upgrade from Laravel 11 to Laravel 12 Without Breaking Changes

Table Of Content

1 Prerequisites

Before diving into the upgrade, ensure your environment meets the requirements for Laravel 12:

  • PHP Version: Laravel 12 requires PHP 8.2 or higher, with strong recommendations for PHP 8.3 for optimal performance. Run php -v in your terminal to check. If needed, upgrade PHP via your server provider (e.g., via apt on Ubuntu or brew on macOS).
  • Composer: Use the latest version of Composer (at least 2.0). Update it with composer self-update.
  • Server Requirements: Confirm your server supports the updated dependencies, including extensions like BCMath, Ctype, JSON, Mbstring, OpenSSL, PDO, Tokenizer, and XML.
  • Backup Everything: Always back up your database, code, and .env file. Use tools like Git for version control or zip your project directory.
  • Testing Environment: Perform the upgrade in a staging or local environment first, not directly on production.

Additionally, review your third-party packages for Laravel 12 compatibility. Tools like Laravel Shift (a paid service) can automate much of this, but we'll cover the manual process here.

2 Introduction

Laravel follows a yearly major release cycle, and version 12 — released in February 2025 — is classified as a maintenance release. Unlike Laravel 9 to 10, which introduced major structural changes, the jump from 11 to 12 is intentionally lightweight. The Laravel team focused on upstream dependency updates, developer experience improvements, and backward-compatible enhancements.

This means most applications running on Laravel 11 with PHP 8.2+ can upgrade with minimal friction. That said, there are a handful of medium- and low-impact changes — like the shift to UUIDv7 and the removal of Carbon 2.x support — that you'll want to handle carefully. This guide covers each one in detail so nothing catches you off guard.

If you're new to the Laravel ecosystem, you may also want to explore our guide on Laravel 12 Eloquent Tips and Tricks for Beginners to strengthen your foundation before upgrading.

3 Backup Your Project

The golden rule of any upgrade: backup first. This prevents data loss if something goes awry.

  • Create a Git branch: git checkout -b upgrade-laravel-12.
  • Backup your database: Use php artisan db:backup if you have a custom command, or export via phpMyAdmin/MySQL Workbench.
  • Copy your project: Duplicate the entire directory or use rsync for large projects.
  • Save composer.json: Copy your current composer.json to a safe location for reference.

This step ensures you can rollback if needed. Remember, Laravel 12 has minimal breaking changes, but custom code or outdated packages might introduce issues. For production apps, consider setting up a Docker environment to test the upgrade in an isolated container before deploying.

4 Update Dependencies

The core of the upgrade involves updating your composer.json file and running Composer commands.

Open composer.json and update the following:

    
        {
            "require": {
                "php": "^8.2",
                "laravel/framework": "^12.0"
            },
            "require-dev": {
                "phpunit/phpunit": "^11.0",
                "pestphp/pest": "^3.0"
            }
        }
    

If you're using Laravel Breeze, Cashier, or other official packages, update them too (e.g., laravel/breeze to ^2.0 if installed). For apps with REST API implementations, make sure your API routes and Sanctum configurations are compatible.

Now, run:

    
       composer update
    

This will fetch Laravel 12 and compatible versions of dependencies. If conflicts arise (e.g., with third-party packages like Inertia.js), resolve them by updating those packages to versions supporting Laravel 12. For example, if you see an error like "inertiajs/inertia-laravel requires laravel/framework ^11.0", update to a compatible version or check their GitHub for Laravel 12 support.

Also, update the Laravel installer if you use it:

    
       composer global update laravel/installer
    

Or re-install via php.new scripts for your OS, as detailed in the official docs. If you run into unexpected errors during this step, check our guide on Common Laravel 12 Errors and How to Fix Them.

5 Handle Breaking Changes and Updates

Laravel 12 documents all potential breaking changes, categorized by impact. Fortunately, there are no high-impact changes, but let's address the medium and low ones to avoid surprises.

Medium Impact: Models and UUIDv7

Laravel now uses UUID version 7 (ordered UUIDs) in the HasUuids trait for better performance in databases. If your models rely on version 4 UUIDs, switch to HasVersion4Uuids:

    
        use Illuminate\Database\Eloquent\Model;
        use Illuminate\Database\Eloquent\Concerns\HasVersion4Uuids as HasUuids;

        class User extends Model
        {
            use HasUuids;
            // Rest of the model...
        }
    

The HasVersion7Uuids trait is removed — use HasUuids directly for v7 behavior. For more on working with models efficiently, see our Laravel 12 Eloquent Tips and Tricks.

Low Impact: Carbon 3

Support for Carbon 2.x is dropped; ensure you're on Carbon 3.x. Update via Composer if needed, and review Carbon's migration guide for any date-handling changes in your code.

Low Impact: Concurrency Result Mapping

When using Concurrency::run with associative arrays, results now preserve keys:

    
        use Illuminate\Support\Facades\Concurrency;

        $result = Concurrency::run([
            'taskA' => fn() => 'Result A',
            'taskB' => fn() => 'Result B',
        ]);
        // Returns: ['taskA' => 'Result A', 'taskB' => 'Result B']
    

Update any code expecting numeric indices.

Low Impact: Container Resolution

The DI container now honors default property values:

    
        class ExampleService
        {
            public function __construct(public ?string $option = null) {}
        }

        $service = app(ExampleService::class);
        // $service->option is null, not auto-injected
    

If you need injection, explicitly pass values.

Low Impact: Image Validation Excludes SVGs

The image rule no longer validates SVGs by default. To allow them:

    
        use Illuminate\Validation\Rules\File;

        $request->validate([
            'photo' => ['required', File::image()->allowSvg()],
        ]);
    

Low Impact: Local Filesystem Root

The default local disk root is now storage/app/private. To revert:

    
        // config/filesystems.php
        'disks' => [
            'local' => [
                'driver' => 'local',
                'root' => storage_path('app'),
            ],
        ],
    

Low Impact: Database Schema Inspection

Methods like Schema::getTables() now include all schemas. Filter with:

    
       use Illuminate\Support\Facades\Schema;

       $tables = Schema::getTables(schema: 'public');
    

Low Impact: Routing and Middleware Compatibility

While there are no major routing changes in Laravel 12, it's worth reviewing your middleware stack for compatibility. If you're using custom middleware or rate limiters, see our Laravel 12 Routing and Middleware Guide for updated patterns and best practices.

Other Changes

  • Nested request merging supports dot notation: $request->mergeIfMissing(['user.name' => 'John']);
  • Token repository constructor uses seconds for expiration.
  • Blueprint constructor requires a Connection instance.

Compare your laravel/laravel repo changes via GitHub for config updates.

6 Run Migrations and Test

After updates, run:

    
        php artisan migrate
    

Test your application thoroughly:

  • Unit/Feature Tests: Run php artisan test or ./vendor/bin/pest to execute your full test suite.
  • Manual Testing: Check all routes, forms, file uploads, and API endpoints manually.
  • Error Logs: Monitor storage/logs/laravel.log for deprecation warnings or unexpected exceptions.
  • Performance: Use tools like Laravel Debugbar or Telescope to verify no performance regressions. For detailed optimization tips, see our Laravel 12 Performance Optimization Guide.

Now that your application is running on Laravel 12, here are some essential guides to help you make the most of the framework's latest features and best practices:

7 Testing and Verifying the Upgrade

Once the upgrade process is complete, it's time to verify everything is working as expected. Run the following steps:

  • Run Unit Tests: Make sure all your unit tests pass after the upgrade. Use php artisan test --parallel to speed up large test suites.
  • Check Routes and Views: Ensure that all routes and views render as expected. Pay special attention to any routes using middleware that may have changed.
  • Check Artisan Commands: Run php artisan list to ensure all commands are still functional, including any custom commands your application depends on.
  • Check Logs: Look at your application logs in storage/logs/laravel.log for any errors, deprecation notices, or warnings after the upgrade.
  • Test Background Jobs: If your app uses queues, verify that jobs are dispatching and processing correctly. See our Laravel 12 Queue and Jobs Tutorial for troubleshooting tips.

8 Conclusion

Upgrading from Laravel 11 to Laravel 12 doesn't have to be a difficult process. By following this step-by-step guide — backing up your project, updating composer.json, handling the UUIDv7 migration, addressing Carbon 3 compatibility, and running thorough tests — you can ensure a smooth transition with minimal disruptions to your application.

The key takeaway is that Laravel 12 is a maintenance-focused release with no high-impact breaking changes. Most applications can upgrade in under 30 minutes, including testing time. Always remember to work in a staging environment first, review the official Laravel 12 upgrade guide, and test every critical path in your application.

Once your upgrade is complete, take advantage of Laravel 12's improvements to enhance your development workflow. Explore our related tutorials below to get the most out of your upgraded application.

Revathi M - PHP and CodeIgniter Developer

Written by Revathi M

PHP Developer & Technical Writer · 10+ years building web applications with CodeIgniter and Laravel

Revathi specializes in PHP backend development, authentication systems, and REST API design. She writes practical, production-tested tutorials at Get Sample Code to help developers build secure applications faster.

Frequently Asked Questions

Laravel 12 introduces official starter kits for React, Vue, and Livewire, powered by Inertia.js. These kits include built-in authentication using either Laravel traditional auth or WorkOS AuthKit, which provides social login, passkeys, and enterprise SSO out of the box. The starter kits replace Laravel Breeze and Jetstream as the recommended scaffolding approach for new projects.

Yes, if you followed the backup steps before upgrading. Revert your composer.json and composer.lock files to their original state, restore your database backup, and run composer install to reinstall the previous dependency versions. Using a dedicated Git branch for the upgrade makes this even easier. Simply switch back to your main branch with git checkout main.

No. Laravel 12 requires PHP 8.2 as the minimum version. PHP 8.3 is strongly recommended for optimal performance and compatibility. If you are still on PHP 8.1, you must upgrade your PHP version before upgrading to Laravel 12. Check your current version by running php -v in your terminal.

You need PHP 8.2 or higher (PHP 8.3 is strongly recommended for best performance), the latest Composer version (2.0+), a complete backup of your project including code, .env file, and database, and confirmation that all your third-party packages support Laravel 12. It is also recommended to perform the upgrade in a staging or local environment before applying it to production. Laravel 12 is a maintenance release, so most Laravel 11 apps upgrade smoothly with minimal changes.

The official Laravel documentation estimates about 5 minutes for simple applications when there are no major third-party package conflicts. Plan extra time for testing, especially in larger projects with custom code or many dependencies.

No high-impact breaking changes exist. Laravel 12 is a maintenance-focused release. The most notable updates include: (1) Carbon 3.x is now required and Carbon 2.x support is removed. (2) The HasUuids trait defaults to ordered UUIDv7, so use HasVersion4Uuids if you need v4 behavior. (3) The local filesystem disk root changed to storage/app/private by default. (4) The image validation rule no longer allows SVGs automatically. (5) Concurrency::run with associative arrays now preserves keys instead of returning numeric indices. (6) The DI container now honors default property values. Most applications require little to no code changes.

Yes, if you use them: update PHPUnit to ^11.0 and Pest to ^3.0 (or later) in the require-dev section of composer.json. Check other dev dependencies for compatibility.

Laravel 12 introduces official starter kits for React, Vue, and Livewire (with an option for WorkOS AuthKit authentication), updates to upstream dependencies for better security and performance, stronger PHP 8.3 alignment, and various small developer experience improvements. It maintains excellent backward compatibility with Laravel 11 applications.

Laravel 12 defaults to UUID version 7 (ordered/time-based) in the HasUuids trait for better database indexing. If your app relies on version 4 UUIDs (random), change your model to use the HasVersion4Uuids trait instead: use Illuminate\\Database\\Eloquent\\Concerns\\HasVersion4Uuids as HasUuids;

First, run `composer why-not laravel/framework 12.0` to see conflicting packages. Then update those packages to their Laravel 12-compatible versions (check their GitHub repos or Packagist). Laravel Shift (automated upgrade service) is also highly recommended for complex projects.