Open-source project
rectorphp/rector avatar
rectorphp/rector

Rector: PHP Upgrades and Refactoring Through an AST

Instant Upgrades and Automated Refactoring of any PHP 5.3+ code

10,430 stars742 forksPHPMIT

At a glance

What is it?
Rector rewrites PHP source automatically, from PHP 5.3 to 8.5 and across framework sets, by parsing code into an abstract syntax tree. It is a dev dependency you run deliberately, and its own README admits the output needs a formatter afterward.
Who is it for?
Adopt Rector if you maintain a PHP codebase that must track language or framework versions and you can run a dry run and review a diff before every apply. Do not adopt it if you expect clean output without a coding standard tool, or if you cannot review large diffs.
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 3 days 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 September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Rector changes, and who ends up running it

Rector is a command line tool that rewrites PHP source code. The README splits its purpose in two: instant upgrades, covering PHP 5.3 through 8.5 plus framework migrations, and automated refactoring for code quality. The audience is a team with an existing PHP application, not a greenfield project. That is because the tool's value comes from the distance between the code you have and the code you want, and that distance only exists after a codebase has aged.

The README frames the second use case around team turnover: keeping quality when new developers join and senior reviewers are not always available. That framing matters, because it tells you Rector is meant to be run repeatedly, not once. A one-off migration is the obvious entry point. Continuous refactoring in CI is the stated long-term pattern, and the README links to a blog post about a setup command for that workflow.

Rector is not a linter. A linter reports; Rector writes. That single difference drives every operational decision around it, from how you run it to what you do with the result.

An AST rewrite, not a text search and replace

The mechanism is an abstract syntax tree. Rector depends on nikic/php-parser, which turns PHP files into a tree of nodes. Rules match patterns in that tree and replace nodes, and the modified tree is written back out as PHP. This is why Rector can change a constructor signature and every call site consistently, which a regular expression cannot do reliably.

The README is explicit about the cost of this design. An AST does not know about spaces, so writing the tree back to a file produces poorly formatted code, in PHP and in docblock annotations alike. That is a documented drawback, not a bug to be patched. The README's answer is that your project needs a coding standard tool with formatting rules, and it points to ECS with the setup used in the rector-src repository.

Rules are the unit of change. You can register a single rule for tight control, or a prepared set such as deadCode or codeQuality that bundles many rules. The README's configuration example shows both at once. That granularity is the main lever you have: a single rule is easy to reason about, a prepared set is a broad sweep.

Installing Rector and running a first dry run

Rector installs as a Composer dev dependency, which keeps it out of production installs. The README gives this exact command:

bash
composer require rector/rector --dev

After installation, running the binary without arguments creates a rector.php file in your root directory:

bash
vendor/bin/rector

That generated file is where you decide what runs. The README's example registers one rule and enables two prepared sets at the same time:

php
use Rector\Config\RectorConfig;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorRector;

return RectorConfig::configure()
    // register single rule
    ->withRules([
        TypedPropertyFromStrictConstructorRector::class
    ])
    // here we can define, what prepared sets of rules will be applied
    ->withPreparedSets(
        deadCode: true,
        codeQuality: true
    );

The dry run is the step that matters. Point it at a directory and Rector prints a diff of the files it would change rather than changing them:

bash
vendor/bin/rector src --dry-run

Read that diff on a small directory before widening the scope. When you are satisfied, drop the flag to apply the changes:

bash
vendor/bin/rector src

What you should expect afterward is working code with formatting you will not like. Run your formatter next.

The formatting debt and the mixed PHP and HTML case

Two limitations are documented in the README and both are worth taking seriously before you commit to Rector.

The first is formatting. Because the AST discards whitespace, every file Rector touches comes back with degraded formatting. This is not optional and it is not configurable away inside Rector. The practical consequence is that Rector is only half a pipeline. Without a coding standard tool to run afterward, your diffs will be noisy and your codebase will drift stylistically. The README states plainly that your project needs such a tool, and points to ECS as the project's own choice. If your team has no formatter, adding Rector means adding one.

The second is files that mix PHP and HTML. The README warns that changes to such files may need manual verification after Rector applies them. Templates, view files and legacy pages with inline markup fall into this category. Treat their output as untrusted until a human has looked at it.

There is also a platform constraint. Parallel mode is described as working most of the time on most operating systems, but on Windows it may fail in ways the troubleshooting guide does not resolve. The suggested workaround is to check whether you are on PowerShell 7 and, if so, switch to command prompt or bash for Windows. That is a real environment limitation, not a configuration detail.

Debugging a rule that does not fire

When a rule does not produce the change you expect, the README offers a debug flag that prints nested exception output:

bash
vendor/bin/rector src/Controller --dry-run --debug

There is also an Xdebug path. Install and configure Xdebug, then add the flag to the same command:

bash
vendor/bin/rector src/Controller --dry-run --xdebug

For inspecting the tree itself, Rector exposes a helper that prints a node as PHP code:

php
use PhpParser\Node\Scalar\String_;
$node = new String_('hello world!');

// prints node to string, as PHP code displays it
print_node($node);

This is the tooling you reach for when you are writing or adapting rules rather than just running prepared sets. It also sets a boundary: understanding why a rule misfires requires reading AST nodes, and the README acknowledges that not everyone wants to spend hours on that, which is why the project sells commercial support.

Rector versus a framework's own upgrade tooling

The closest alternative is a framework's own migration tooling. Symfony, for example, maintains a separate rector-symfony set, and the README lists community-maintained sets for Drupal, Craft CMS, Shopware, TYPO3, Sulu, Nette, Sylius, CakePHP, Laravel, Contao, Ibexa, SilverStripe and Yii2, among others. That list is itself the argument: Rector is a general engine, and framework-specific knowledge lives in sets maintained outside the core repository.

The difference in approach is where the rules come from. A framework's own upgrade guide tells you what changed and leaves the edits to you, or ships a narrow script for one version jump. Rector applies rules directly to your source and shows you the diff. The trade-off is coverage versus currency. Core sets track PHP itself and general code quality, while the framework sets are maintained by their own communities, so their completeness and their release cadence are not the core project's responsibility. Before relying on a framework set, check that repository rather than assuming it moves in step with Rector's own releases.

A static analyser is not a substitute here. It will tell you that a call is wrong; it will not rewrite the call. The two are complementary, and the README links to a rector-rule package that bridges static analysis findings into Rector rules.

Maintenance, licence and the real upgrade cost

The repository is not archived, and the last push was on 2026-09-21. Releases are frequent: 2.6.7 on 2026-09-13, 2.6.6 on 2026-09-02, and 2.6.5 on 2026-08-30. The project is MIT licensed, which permits commercial use and modification; this is a statement about the licence text, not legal advice, and your own compliance review still applies.

The upgrade cost is not in the Composer command. It is in the review. Because Rector rewrites source, every applied run is a code change that someone should read. The dry run exists precisely to make that review possible before the change lands, and the README's CI framing assumes you will automate the check rather than the apply. Budget for the formatting pass as well: if your codebase has no coding standard tool today, the first Rector run is also the moment you adopt one.

The project also offers paid support for teams that want the migration done without learning the AST layer themselves. That is a legitimate option and the README states it openly, which is more honest than most projects manage.

Editorial conclusion

Adopt Rector if you maintain a PHP codebase that must track language or framework versions and you can run a dry run and review a diff before every apply. Do not adopt it if you expect clean output without a coding standard tool, or if you cannot review large diffs. Before the first real run, verify that rector.php registers only the rules you intend and that vendor/bin/rector src --dry-run produces a diff you can read.

Frequently asked questions

How do I install Rector?

Install it as a Composer dev dependency with composer require rector/rector --dev. Running vendor/bin/rector afterward creates a rector.php configuration file in your root directory.

How do I use Rector on a PHP project?

Configure rules in rector.php using withRules for a single rule or withPreparedSets for groups such as deadCode and codeQuality. Then run vendor/bin/rector src --dry-run to see the diff, and drop the flag to apply the changes.

What is Rector in the PHP ecosystem?

Rector is a tool that instantly upgrades and refactors PHP code, supporting upgrades from PHP 5.3 to 8.5 as well as framework migrations. It works by parsing code into an abstract syntax tree and rewriting nodes.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. rectorphp/rector on GitHub
  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/rectorphp-rector.svg)](https://hysenlabs.com/projects/rectorphp-rector)