Upgrades a Laravel application or package to a newer Laravel version using Rector and driftingly/rector-laravel. Inspects composer.json, detects current and target versions, configures Rector with the correct LaravelSetList or LaravelLevelSetList rulesets, updates dependencies conservatively, runs a dry-run first, and produces an upgrade checklist covering both automated code changes and manual skeleton/breaking-change steps. The latest stable Laravel version is Laravel 13 (March 2026). Activate for phrases like "upgrade to Laravel 12", "upgrade to Laravel 13", "migrate my Laravel app", "fix Laravel deprecation warnings", "help me with the Laravel upgrade guide", "set up Rector for Laravel upgrade", or any request to automate a Laravel version migration — even when Rector is not mentioned by name.
74
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
You are helping upgrade a Laravel application or package to a newer Laravel version using Rector and the driftingly/rector-laravel community ruleset.
Current stable Laravel version: Laravel 13 (released March 2026). Default to this when the user hasn't specified a target.
| Laravel | Minimum PHP | Supported PHP |
|---|---|---|
| Laravel 10 | PHP 8.1 | 8.1 – 8.3 |
| Laravel 11 | PHP 8.2 | 8.2 – 8.4 |
| Laravel 12 | PHP 8.2 | 8.2 – 8.5 |
| Laravel 13 | PHP 8.3 | 8.3 – 8.5 |
Important: Laravel 13 drops PHP 8.2 support entirely. If the project is on PHP 8.2, a PHP upgrade to 8.3+ is required before or alongside the Laravel 13 upgrade.
Always check PHP version first — if the project needs a PHP upgrade too, use the php-update-with-rector skill in tandem.
When upgrading to Laravel 13, verify the environment meets these requirements:
PHP extensions required: BCMath, Ctype, cURL, DOM, Fileinfo, Filter, Hash, JSON, Mbstring, OpenSSL, PCRE, PDO, Session, Tokenizer, XML
Minimum database versions:
| Database | Minimum version |
|---|---|
| MySQL | 5.7 |
| MariaDB | 10.3 |
| PostgreSQL | 10.0 |
| SQLite | 3.26.0 |
| SQL Server | 2017 |
Composer: 2.x required
Key dependency changes (L12 → L13):
| Package | Laravel 12 | Laravel 13 |
|---|---|---|
phpunit/phpunit | ^11.0 | ^12.5 |
pestphp/pest | ^3.0 | ^4.0 |
laravel/tinker | ^2.0 | ^3.0 |
nunomaduro/collision | ^8.0 | ^8.6 |
nesbot/carbon | ^3.0 | ^3.0 (unchanged) |
Flag any of these in composer.json when upgrading — they need aligned upgrades.
LaravelSetList or LaravelLevelSetList constantsRead these files before proposing anything:
composer.json — Laravel version constraint, PHP constraint, dependenciescomposer.lock — actual installed laravel/framework versionvendor/composer/installed.json — if available, for precise package versionsrector.php or rector.php.dist — existing Rector config if presentphpunit.xml* — test frameworkphpstan.neon* or larastan config — static analysisbootstrap/app.php — detect L11+ skeleton vs L10-styleapp/Http/Kernel.php — presence indicates pre-L11 skeletonDetermine:
"laravel/framework": "^11.0")composer require rector/rector --dev
composer require driftingly/rector-laravel --devUpdate the Laravel constraint in composer.json to match the target version:
"require": {
"laravel/framework": "^13.0"
}Check for blocking dependencies before updating:
composer why-not laravel/framework ^13.0Ecosystem packages that often need aligned major version upgrades:
Flag any of these found in composer.json and recommend checking each package's own upgrade guide.
rector.phpGenerate bootstrap if none exists:
vendor/bin/rector initUse LaravelSetList to apply rules for one specific version:
use Rector\Config\RectorConfig;
use RectorLaravel\Set\LaravelSetList;
return RectorConfig::configure()
->withPaths([
__DIR__ . '/app',
__DIR__ . '/database',
__DIR__ . '/routes',
__DIR__ . '/config',
__DIR__ . '/tests',
])
->withSkip([
__DIR__ . '/vendor',
__DIR__ . '/storage',
__DIR__ . '/bootstrap/cache',
__DIR__ . '/public',
])
->withSets([
LaravelSetList::LARAVEL_130, // adjust to target
]);LaravelSetList constants (one version at a time, NOT cumulative)| Constant | Target |
|---|---|
LaravelSetList::LARAVEL_90 | Laravel 9 |
LaravelSetList::LARAVEL_100 | Laravel 10 |
LaravelSetList::LARAVEL_110 | Laravel 11 |
LaravelSetList::LARAVEL_120 | Laravel 12 |
LaravelSetList::LARAVEL_130 | Laravel 13 |
Use LaravelLevelSetList to apply all rules up to a target version in one pass:
use RectorLaravel\Set\LaravelLevelSetList;
->withSets([
LaravelLevelSetList::UP_TO_LARAVEL_130, // applies L9 through L13 rules cumulatively
])Available: UP_TO_LARAVEL_90, UP_TO_LARAVEL_100, UP_TO_LARAVEL_110, UP_TO_LARAVEL_120, UP_TO_LARAVEL_130.
For large jumps, cumulative sets are convenient but produce larger diffs — use individual sets with commits between each for more reviewable changes.
// Pass 1: apply in rector.php, then commit
->withSets([LaravelSetList::LARAVEL_110])
// Pass 2
->withSets([LaravelSetList::LARAVEL_120])
// Pass 3
->withSets([LaravelSetList::LARAVEL_130])If also upgrading PHP at the same time:
use Rector\Set\ValueObject\LevelSetList;
->withSets([
LevelSetList::UP_TO_PHP_84, // PHP rules first
LaravelLevelSetList::UP_TO_LARAVEL_130, // then Laravel rules
])->withPaths([
__DIR__ . '/src',
__DIR__ . '/tests',
])
// Do NOT include app/, database/, routes/ — those are application-only paths# 1. Install Rector + Laravel ruleset
composer require rector/rector --dev
composer require driftingly/rector-laravel --dev
# 2. Dry-run — preview only, no writes
vendor/bin/rector process --dry-run
# 3. Review the diff, adjust rector.php if needed, repeat dry-run
# 4. Apply changes
vendor/bin/rector process
# 5. Clear caches
php artisan config:clear && php artisan route:clear && php artisan cache:clear
# 6. Quick sanity checks
php artisan route:list
php artisan config:show app
# 7. Format (if Pint configured)
vendor/bin/pint
# 8. Static analysis (if Larastan configured)
vendor/bin/phpstan analyse
# 9. Run tests
composer test
# 10. Check official upgrade guide for manual stepsCommit after each logical batch:
git add -A && git commit -m "chore: apply Rector Laravel 13 upgrade rules"Rector handles code-level changes automatically. These are the manual items to include in the upgrade checklist for each version.
Rector rules applied by LARAVEL_130: (check driftingly/rector-laravel changelog for current rule list)
Manual checks:
Rector rules applied by LARAVEL_120:
ContainerBindConcreteWithClosureOnlyRector — container binding pattern changesScopeNamedClassMethodToScopeAttributedClassMethodRector — scope methods converted to #[Scope] attributesRenameMethodRector — Request::get() renamed to Request::input()Manual checks:
HasUuids now generates UUIDv7 — if you rely on UUIDv4 ordering, add HasVersion4Uuids traitConnection instance; affects custom database classesDatabaseTokenRepository — $expires constructor arg now in seconds (not minutes)storage/app to storage/app/privateFile::image(allowSvg: true) to re-allowConcurrency::run() — results now preserve associative array keysOfficial guide: https://laravel.com/docs/12.x/upgrade
Rector rules applied by LARAVEL_110: method renames, deprecated patterns, updated signatures.
Manual checks (skeleton restructuring — optional but recommended):
bootstrap/app.php — new Application::configure() format; middleware registered hereapp/Http/Kernel.php removed — middleware moves to bootstrap/app.phpapp/Console/Kernel.php removed — scheduled tasks move to routes/console.phpapp/Exceptions/Handler.php removed — exception handling in bootstrap/app.phpAppServiceProvider takes overOfficial guide: https://laravel.com/docs/11.x/upgrade
$dates property on models deprecated — migrate to $castsOfficial guide: https://laravel.com/docs/10.x/upgrade
Always provide:
rector.php config — ready to use with correct LaravelSetList or LaravelLevelSetList| Error | Fix |
|---|---|
Class RectorLaravel\Set\LaravelSetList not found | composer require driftingly/rector-laravel --dev |
LARAVEL_120 or LARAVEL_130 constant not found | composer update driftingly/rector-laravel to get the latest version |
Composer conflict after composer update | composer why-not laravel/framework ^13.0 |
| App boots but routes return 500 | Check service providers and middleware registration (L11+ skeleton) |
| Rector makes no changes | Verify withPaths() points to actual app directories |
| Tests fail after apply | Revert specific file with git checkout, add rule to withSkip(), re-run |
| Carbon errors after L12 upgrade | Update Carbon to v3: composer require nesbot/carbon:^3.0 |
22c7c54
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.