Open-source project
driftingly/rector-laravel avatar
driftingly/rector-laravel

Rector rules for Laravel, and the version sets that do the guessing

Rector upgrades rules for Laravel

1,300 stars122 forksPHPMIT

At a glance

What is it?
rector-laravel is a Rector extension maintained by the Laravel community that ships upgrade rules keyed to framework versions, plus quality sets for idiomatic code. The current recommended setup reads your composer.json and applies the version sets matching what you have installed, which replaces the older manual list of level sets.
Who is it for?
rector-laravel suits Laravel teams planning a framework upgrade, since the version sets are the part that would otherwise be manual work, and it suits teams who want idiomatic Laravel style enforced by a tool rather than by review comments.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • driftingly/rector-laravel1,300 ★ · +11
Star history
Repository2026-10-192026-11-07
driftingly/rector-laravel1.3k1.3k

11 Stars in the last 19 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

A community extension, and what it adds to Rector itself

rector-laravel is a Rector extension for automated upgrades, developed by the Laravel community. Rector is the tool that rewrites your source code according to rules, working on the abstract syntax tree rather than on text, which is why the topics attached to this repository include ast and instant-upgrades.

The extension exists because Laravel has conventions and deprecations that Rector cannot know about on its own. Rules for additional first-party packages are included as well, with Cashier and Livewire named explicitly, and the package sits on Packagist as driftingly/rector-laravel with a version badge and a download count badge in the README header.

Installation is a Composer dev dependency, which is the right scope for a tool that modifies code:

bash
composer require --dev driftingly/rector-laravel

The rules themselves live in config/sets/ inside the repository, one PHP file per set, and the repository layout is more than just the rules. There is a src/ directory for the rule implementations, stubs/ for code Rector needs to resolve framework classes against, templates/ for generated code, commands/ for the command layer, build/ for the build scripts, tests/ for the test suite, and a docs/ directory. The presence of phpstan.neon, phpunit.xml and duster.json in the root is worth noting: the package runs static analysis, unit tests and a code style tool on itself, so the rules are held to a standard that a script collection usually is not.

withComposerBased reads composer.json and picks the version sets

The recommended way to configure the extension is a single call that lets the tool detect your installed versions:

php
<?php declare(strict_types=1);

use Rector\Config\RectorConfig;

return RectorConfig::configure()
    ->withComposerBased(laravel: true, /** other options */);

The README says this registers RectorLaravel\Set\LaravelSetList::COMPOSER_BASED, which applies the version sets of Laravel and of Faker, Livewire and Cashier, when installed, up to the installed version. That is the whole point of the feature. Detecting the version in composer.json means the same configuration file works on a project still on Laravel 11 and on one already on Laravel 13, which matters for applications that upgrade in stages or that support several versions of a package.

The older approach is still documented but explicitly deprecated. The version set lists are deprecated in favor of withComposerBased, and they will be removed in a future major version. The manual form uses LaravelLevelSetList and picks the constant for your target version:

php
<?php declare(strict_types=1);

use Rector\Config\RectorConfig;
use RectorLaravel\Set\LaravelLevelSetList;

return RectorConfig::configure()
    ->withSets([
        LaravelLevelSetList::UP_TO_LARAVEL_130,
    ]);

Sets for higher versions include the sets for lower versions, so the level lists are cumulative. There is also a distinction between the two families of sets that is easy to miss. The version sets in LaravelSetList only contain changes related to a specific version upgrade, and the rules in LaravelSetList::LARAVEL_130 apply when upgrading from Laravel 12 to Laravel 13. So LaravelLevelSetList is about moving between framework versions, while the quality entries in LaravelSetList are about the shape of your code.

The quality sets, and what they actually rewrite

The second family of sets is where the day-to-day value is. These are not tied to a version, they are tied to a style, and the README describes each one in a table.

The clearest example is LARAVEL_ARRAYACCESS_TO_METHOD_CALL, which converts uses of things like $app['config'] to $app->make('config'). The motivation is obvious once you see it: array access on the container is opaque to a static analyser, while the make method is not. The related LARAVEL_CONTAINER_STRING_TO_FULLY_QUALIFIED_NAME set changes the string or class constant used for a service container make call, which keeps the target type visible at the call site.

LARAVEL_ARRAY_STR_FUNCTION_TO_STATIC_CALL converts most string and array helpers into the static calls of the Str and Arr facades, and the README links the Laravel facades documentation for the difference between facades and helper functions. LARAVEL_CODE_QUALITY replaces a magical call on $this->app["something"] with a standalone variable carrying PHPDocs, so the type is written down rather than inferred from a magic lookup.

Two of the sets change behaviour in ways that need care. LARAVEL_ELOQUENT_MAGIC_METHOD_TO_QUERY_BUILDER transforms magic method calls on Eloquent models into corresponding Query Builder method calls, which is a real semantic change rather than a rename. And LARAVEL_COLLECTION improves the usage of Laravel collections by using simpler, more efficient or more readable methods.

There is also LARAVEL_FACADE_ALIASES_TO_FULL_NAMES, which replaces facade aliases with full facade names. That is a mechanical change that touches a lot of files, and it is the kind of rule that produces a large diff with no behaviour difference at all, which is both its use and its annoyance.

Finding the rules, including the ones not yet released

The full rule list is documented at docs/rector_rules_overview.md, and the README makes a point of its scope that is worth repeating. The list includes even the rules that are not yet released, but which are available under the dev-main branch. So the overview document doubles as a preview of what the next release will contain, which is a useful thing to have in a package that follows the framework's own release rhythm.

For rules that are already out, the README points at the Rector Find Rule page, filtered to the laravel set group, which searches across Rector's entire catalogue. That distinction matters in practice. Rector has a large core catalogue of rules that are not Laravel specific, such as PHP version migration rules, and the Find Rule page is where you look for those, while the extension's own overview is where you look for framework specific rewrites.

The release history shows how closely the package tracks framework events. The recent tags are 2.6.2 from 2026-08-29, 2.6.1 from 2026-08-27 and 2.6.0 from 2026-08-25, and the last push was on 2026-10-09. The repository is not archived, and the project is MIT licensed with the LICENSE file at the root.

The project's home page is getrector.org, and the badges in the README header show that the package runs both a test suite and a code analysis workflow on every change. That combination is the reason you can reasonably trust a rewrite rule: it is tested against a fixture, and the fixture set is large enough that a rule which broke on common code would fail the build.

What Rector will not do, and how to run this without regret

The honest limit here is the same one that applies to every AST rewriting tool. Rector changes what your code does, not just how it looks, and it does that without a type checker or a runtime in front of it. The Eloquent magic method set is the clearest example, where a rewrite from model magic calls to query builder calls can change a return type or a chain in ways only your tests will notice.

The mitigation is not a Rector configuration setting. It is a green test suite before you start, so that a diff means something. Run Rector on a single set at a time rather than the whole catalogue, read the diff for that set, and commit between sets. A large diff that mixes quality rewrites with version migrations is much harder to review than six small ones.

There is also a category of code Rector cannot see. Facade calls resolve at runtime through the container, so a rewrite that changes which class a string points to can only be verified by running the application. Dynamic configuration, service providers registering bindings at runtime, and anything driven by database contents are all outside the AST. The rule set that concerns the container is a good example of a rewrite that is mechanically correct and still needs a smoke test.

Finally, a note on the deprecation. The manual LaravelLevelSetList approach still works today, but the README says it will be removed in a future major version. If you are setting this up fresh, withComposerBased is the form to write, and if you are copying an older tutorial that uses the level lists, that is a reason to revisit the configuration rather than a reason to avoid the tool.

Editorial conclusion

rector-laravel suits Laravel teams planning a framework upgrade, since the version sets are the part that would otherwise be manual work, and it suits teams who want idiomatic Laravel style enforced by a tool rather than by review comments. It is the wrong choice if you only need one isolated refactoring, since a Rector configuration file is more setup than a single hand edit, and it is the wrong choice if your codebase is large and untested, because the rewrites are semantic and Rector will happily apply them to code you cannot verify. Before running it, confirm your test suite passes on the current version so you can measure what the rewrite changed, read docs/rector_rules_overview.md for the full rule list including unreleased ones, and note that the manual LaravelLevelSetList configuration is deprecated in favour of withComposerBased.

Frequently asked questions

How do I install rector-laravel?

Add it as a development dependency with composer require --dev driftingly/rector-laravel. The package is a Rector extension developed by the Laravel community and is published on Packagist as driftingly/rector-laravel.

What does withComposerBased do in a Rector config?

It registers RectorLaravel\Set\LaravelSetList::COMPOSER_BASED, which detects the installed versions from composer.json and applies the version sets of Laravel, and of Faker, Livewire and Cashier when they are installed, up to the installed version.

What is the difference between LaravelSetList and LaravelLevelSetList?

The version sets in LaravelSetList only contain changes related to a specific version upgrade, for example the rules in LARAVEL_130 apply when going from Laravel 12 to 13. LaravelLevelSetList is the manual, cumulative list of levels such as UP_TO_LARAVEL_130, and the README marks the manual approach deprecated in favor of withComposerBased.

Where can I find the list of Laravel Rector rules?

The full list is in docs/rector_rules_overview.md, and it includes rules that are not yet released but are available on the dev-main branch. Released rules can also be found on the Rector Find Rule page with the laravel set group filter.

Which quality rules are the most disruptive to apply?

LARAVEL_ELOQUENT_MAGIC_METHOD_TO_QUERY_BUILDER transforms magic method calls on Eloquent models into Query Builder calls, which is a semantic change rather than a rename, and sets that rewrite container access change what runs at runtime. The README lists each set's purpose in a table, and applying one set at a time makes the diff reviewable.

Official sources

  1. driftingly/rector-laravel on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/driftingly-rector-laravel.svg)](https://hysenlabs.com/projects/driftingly-rector-laravel)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/driftingly-rector-laravel.svg)](https://hysenlabs.com/projects/driftingly-rector-laravel)

Was this useful?