Learn about Rector, Upgrades and Planning

Notes on automated refactoring, static analysis and keeping PHP projects alive.

Use Rector on Your Drupal Site Easier Than Ever with New Composer-based Sets
As of Rector 2.5, Composer-based sets now support Drupal! Instead of manually adding dozens of configuration sets and keeping the list up to date as y...
Upgrade to PHPUnit 12.5 in 7 Diffs
PHPUnit 12 was released a year ago, but only PHPUnit 12.5 released in December 2025 includes valuable features that are worth it. The most important...
Introducing Safe and Progressive Strict Type Adoption Rule
PHP's `declare(strict_types=1)` directive is a powerful tool for preventing subtle bugs. Yet most existing, mature projects don't use it consistently,...
Make PHPUnit tests Perfect in 15 Diffs
Rector helps you improve PHP code, upgrade it to latest PHP version, make use of modern features and faster code structures. But did you know it can...
Rector 2.2: New rules for Array Docblocks
As you know, we provide an [upgrade services](https://getrector.com/hire-team) to speed up the modernization of codebases. Part of this service is get...
Introducing Rector Jack: Raise Your Dependencies Safely
Hey PHP folks! 👋 We're thrilled to share **Jack**, a new experimental CLI tool to help you lift your Composer dependencies one version at a time &nda...
How to install old or new PHP on non-LTS Ubuntu
Legacy projects can be upgraded in 2 directions - PHP-wise and infrastructure-wise. We can get a new Ubuntu 25 but still have to run old PHP. The sam...
How to Strangle your Project with Strangle Anti-Pattern
Nearly half of the projects we help upgrade have tried the upgrade before on their own. They've introduced the infamous "strangle pattern". It's a way...
Road to Hell is Paved with Strings
In [7 Traits of Successful Upgrade Companies](/blog/7-traits-of-successful-upgrade-companies), we wrote about the behavior patterns of companies that...
Evolution of New Rector Logo
After 7 years since the first Rector commit, we have a new logo! Today, we're proud to share a streamlined, smooth, and modernized version of the Rec...
5 New Features in Rector 2.0
Rector 2 is out! We've upgraded to PHPStan 2 and PHP-Parser 5. Based on testing on several huge legacy projects, Rector now runs **10-15 %** fast...
Introducing Composer Version-Based Sets
Packages that ship a lot of versions can have a lot of sets to apply. For, twig/twig has 6 sets in Rector, a couple for v1 and a couple for v2. What a...
Improving Rector Performance by 20-30 %
Today I want to talk about how I added an optimization that made Rector 20-30% faster!
Rector is joining the Open Source Pledge
Our business is built on open-source and with open-source software. We're using "free" PHP language, "free" PHP frameworks, and "free" packages. But t...
How to Migrate CodeIgniter to Symfony or Laravel
CodeIgniter was created in 2006 and was one of the first MVC PHP frameworks. Yet it never gained traction and got stuck. Is your project running Code...
Introducing Rule Finder
To this day, Rector provides **over 535 rules spread in 4 repositories** - core, PHPUnit, Symfony, and Doctrine. If you are looking for a rule that do...
Introducing Type Perfect for extra Safety
When dealing with legacy, we first focus on safety by knowing the important types. Code must have reliable type declarations to be refactored safely....
5 Tricks to Write Better Custom Rules
Rector and its [extensions](https://github.com/rectorphp/rector/?tab=readme-ov-file#empowered-by-community-heart) already consist of many rules for PH...
Migrate DateTime to Carbon
Carbon is an excellent library for working with dates and times in PHP. It's being used [by Laravel](https://medium.com/@mhmmdtech/datetime-handling-i...
7 Traits of Successful Upgrade Companies
For the past 10 years, we've been working with over 50 companies on legacy PHP upgrades. We've already written about our approach and technical proces...
Upgrade Legacy Framework or Change it for Another?
Would you upgrade your Nokia 3310 to a newer Nokia or change it to an iPhone with USB-C? Would you upgrade your old Ford Fiesta to a newer Ford or cha...
How to Upgrade Zend Legacy Project
Zend is the second most requested project upgrade in our client group and online forums. If you have no idea where to start, how should you approach t...
How to Upgrade Phalcon project
Phalcon is a PHP framework that is written in C and is known for its speed. It was created in 2012 and it has own PHP-like language - Zephir. After Ca...
Rector 1.0 is Here
The stable Rector version is here. It was about time and we've done all planned changes by the end of 2023.
What to expect when you plan to Migrate Away from CakePHP 2
What is the most requested project we get from our clients? PHP upgrade, Symfony upgrade, framework switch... yes, these belong to the most common one...
Grab Fresh Book Release with Rector 1.0
We are thrilled to introduce the latest update to our book, along with long-awaited **Rector 1.0** from February 2024. This release includes 2 new com...
Modernize Symfony Configs
Symfony configs in YAML are a pile of strings. No IDE autocomplete, no static analysis, and no `@deprecated` warning when an option is on its way out....
5 Common Mistakes in Rector Config and How to Avoid Them
Rector is becoming a standard tool to automate PHP/package upgrades and code quality improvements. Last month, we crossed 60 000 downloads a day. Pas...
Rector 0.17 - Using Scoped Traverse to Locate Specific Node
Rector [no longer supports parent node lookup](/blog/rector-017-brings-more-robust-and-lighter-node-tree) since version 0.17. To look up a specific no...
Rector 0.18 - From Symfony Container to Laravel and How to Upgrade your Extensions
Since the first Rector version, we used Symfony container to inject the services. It worked very well. The new PHP 8.0 came with attributes, and Symfo...
Rector 0.18 - How we made tests Seven Times Faster
The developer experience is a priority when it comes to contributing tools, fixing bugs, and delivering merge requests fast. Rector 0.17 tests could *...
Rector 0.18 - Refocus on PHP
Before going to Rector 1.0, we need to refocus solely on PHP files. In this release, we're leaving a not-so-well-known feature that could handle some...
Rector 0.17 brings More Robust and Lighter Node Tree
Rector has matured enough to start thinking about a stable version. This year, we want to release Rector 1.0. Before that happens, we want to ensure i...
Faster Rector on 0.15.22
Correctness has more priority than speed. Since version 0.14.x, Rector has better scope refresh handling for multiple rules and handle more crash that...
New command to add Rector to your CI in seconds
We're working hard to make the developer experience as smooth as possible. The fewer steps to your first run and full automation with Rector, the bett...
How to Upgrade to PHPUnit 10 in Diffs
PHPUnit 10 [was released today](https://phpunit.de/announcements/phpunit-10.html). Do you fancy an early upgrade? We'll show you how to do it with Re...
New in Rector 0.15: Complete Safe and Known Type Declarations
Rector is helping with PHP upgrades and framework migrations. It also helps to [rise the type coverage](https://tomasvotruba.com/blog/how-to-measure-y...
Separating Laravel and CakePHP as Community Packages
Rector is built for and on the whole PHP community right from the start. But there are also somewhat "local" PHP communities around a specific framewo...
Support for Nested Doctrine Annotation to Flat Attributes in Rector 0.14
We added support for [annotation to attribute upgrade](/blog/how-to-upgrade-annotations-to-attributes) in Rector 0.12. Since then, PHP 8.1 has come wi...
Tests Made Simpler in Rector 0.14
In August, we've been working hard to make Rector lighter. As use the count of users grows, developers use Rector on more legacy projects than before,...
Interview: Legacy Code, Javascript Transpilers and Rector Challenges
I'll be speaking there in October at Paris on [Forum PHP 2022](https://event.afup.org/) about Rector. I was asked for a simple interview to warmup the...
Separating Typo3 and Nette as Community Packages
When Rector started, it was a small project that handled upgrading a vast amount of PHP packages. As the project grew and expanded, more local PHP co...
How to Automatically Add Return Type Declarations without Breaking Your Code
Code filled with docblocks param, var, and return types is a gold mine. Not in the meaning of valuable resource, but rather as exploding metal covered...
New in Rector 0.13 - Refresh Scope for Changed Nodes
Rector is using PHPStan to detect types of various expressions. That means every node has access to [PHPStan `Scope`](https://phpstan.org/developing-e...
New in Rector 0.12 - Introducing Rector Config with Autocomplete
Rector is using Symfony container configuration to build the service model. While it brings automated autowiring, array autowiring, and native contain...
Success Story of Automated Framework Migration from FuelPHP to Laravel of 400k+lines Application
Today, I'm very excited to talk about the full story of our successful automated framework migration how Rector saved our product by refactoring our 4...
How to Migrate Legacy PHP Applications Without Stopping Development of New Features
Migrating legacy PHP applications is always a challenging task. Today I'll introduce one strategy to make these migrations easier by using the power...
New in Rector 0.12 - Much Simpler and Safer Rule Configuration
Configurable rules are the most powerful building stone for instant upgrade sets. Do you want to upgrade from Symfony 5 to 6? You'll primarily deal wi...
New in Rector 0.12 - The Latest PHP in a Single Import
The most used feature of Rector is to keep you updated with the latest PHP. PHP 8.1 was released almost a month ago, so many projects started to use R...
How all Frameworks can Bump to PHP 8.1 and You can Keep Using Older PHP
Imagine **hypothetical situation**: new major Symfony and Laravel are released in December 2021. We'll already have PHP 8.1 out by that time. There ha...
How to Upgrade Annotations to Attributes
We used `@annotations` in PHP 7.4 and below. Now we can use native `#[attributes]` in PHP 8. They have better support in PHPStan and Rector, thanks to...
Dropping Docker in Favor of Composer Install for Better Developer Experience
Some developers see Docker as default-to-use for Rector. Yet they struggle to run it successfully with fundamental changes like [renaming class from u...
How to bump Minimal PHP Version without Leaving Anyone Behind?
Last week we introduced [Prefixed Rector by Default](/blog/prefixed-rector-by-default). The main advantage of this release is that you have a single p...
Prefixed Rector by Default
Today we're introducing a big step up in making Rector developer experience more smooth and intuitive. It will also ease development for Rector contri...
From Doctrine Annotations Parser to Static Reflection
Until recently, we used doctrine/annotations to parse class annotations that you know `@ORM\Entity` or `@Route`. Last 2 weeks, we **rewrote this parse...
Rector 0.10 Released - with PHP 7.1 Support
Today we're releasing Rector that brings the most significant improvement for usability yet. It took 2 months of hard work of our team and Rector comm...
Legacy Refactoring made Easy with Static Reflection
Properly configured class autoloading have been a big ~~requirement~~ problem for many projects that do not use flawless PSR-4 autoload. It took two m...
How much does Single Type Declaration Know?
When it comes to completing type declaration from docblocks, we rely on trust and hopes in commented code. One way out of is [dynamic analysis](https:...
How to Instantly Decouple Symfony Doctrine Repository Inheritance to Clean Composition
Do your Doctrine repositories extend a parent Symfony service? Do you use magic methods of parent `Doctrine\ORM\EntityRepository`? Would you like **sw...
How to Instantly Refactor Symfony Action Injects to Constructor Injection
Action Injections are much fun a first, but they turn your fresh project into legacy code very fast. With PHP 8 and promoted properties, there is no r...
Smooth Upgrade to Nette 3.1 in Diffs
Nette 3.1 was released almost a month ago. Packages using it had enough time to give support to small BC breaks and now it's ready to run on your proj...
Switch Symfony String Route Names to Constants
Last December, we started to use PHP 8.0 and Symfony 5.2. This exact combination opens [many cool tricks](https://tomasvotruba.com/blog/2020/12/21/5-n...
7 Valuable Lessons We Learned from our Clients in 2020
2020 was a big year for us. We had 4 large projects with only tests in CI. Adding ECS with 10 basic sets, PHPStan to level 8, PSR-4 to all classes. In...
Rector 0.9 Released ❄️
More than 45 days have passed since the last Rector release. Since then, we pushed 292 commits in over 220 pull-requests. No wonder the most common qu...
4 Configurable PHPStan rules that Help Rector Merge 188 pull-requests a Month
Last month, we merged a total [188 pull-requests](https://github.com/rectorphp/rector/pulse/monthly) to Rector code. We could not afford such a high r...
Laravel Facades to Constructor Injection: Replace Facade Aliases with Full Classes in 2 hours
Laravel facades are known as [static service locators](https://sergeyzhuk.me/2016/05/27/laravel-facades/). The idea is get any service anywhere, which...
Smooth Upgrade to PHP 8 in Diffs
PHP 8 was released more than 2 weeks ago. Do you want to know what is new? Check [colorful post series about PHP 8 news](https://stitcher.io/blog/new-...
How to make Rector Contribute Your Pull Requests Every Day
Rector can upgrade legacy code to a modern one. But in reality, that's ~5 % of usage. On the other hand, **more than [300 projects](https://packagist....
How to Inline Value Object in Symfony PHP Config
Rector uses [PHP Symfony configs](/blog/2020/08/31/rector-is-moving-from-yaml-to-php-configs-what-changes-and-how-to-get-ready) for [many good reasons...
Rector is Moving From YAML to PHP Configs - What Changes and How to Get Ready?
In July 2020, we started to move from the configuration in YAML to one defined in PHP. The YAML configuration **is now deleted in Rector core** and wo...
How to Migrate From PHPExcel to PHPSpreadsheet with Rector in 30 minutes
[PHPExcel](https://github.com/PHPOffice/PHPExcel) is a package for working with Excel files in PHP. The last version was released in 2015, and it was...
Upgrading Glami to PSR-4, part 1: What and why?
In April 2019 we upgraded [Glami](https://glami.cz)'s big codebase to follow PSR-4. **It was a great success! In this part, we will go through what P...
How to install Rector despite Composer Conflicts
Rector is a composer package. If you install it, it has to meet install requirements conditions. **But how can you [upgrade your Symfony 2.8](https:/...