rector/extension-installer
A Composer plugin that automatically registers installed Rector extensions, so custom rules and configurations load without manual setup. It simplifies adding third-party Rector packages to projects and keeps configuration minimal.
rector/extension-installer is a Composer plugin that removes the need to hand-edit rector.php every time you install a Rector ruleset package. Extension packages tag themselves as rector-extension, and the plugin generates a config file that Rector loads automatically.
Minimum setup (consumer side):
composer require --dev rector/extension-installer
{
"config": {
"allow-plugins": {
"rector/extension-installer": true
}
}
}
composer require --dev <vendor>/<rector-extension>
composer dump-autoload
Where to look first:
vendor/rector/extension-installer/ — the plugin itself and the generated config file it writes (typically src/GeneratedConfig.php; confirm the exact path for your installed version).vendor/composer/installed.json — look at each package's type and extra keys to confirm which extensions the plugin will discover.rector.php — confirm the generated file is actually being imported, and that you are not also hand-importing the same extension (double rules).First use case: you have a rector.php with three manual $rectorConfig->import(...) lines for ruleset packages. Replace those with the plugin, run vendor/bin/rector process --dry-run, and verify the active rule list is unchanged. If it matches, you have a working baseline and can add future extensions with composer require alone.
Consumer pattern — "install and forget". Treat the plugin as infrastructure: install it once, commit the allow-plugins entry, and never touch rector.php when onboarding a new ruleset. Keep rector.php for project-local configuration (paths, sets, skips) only.
Extension author pattern. If you publish a Rector ruleset, declare it so the plugin can find it:
{
"type": "rector-extension",
"extra": {
"rector": {
"includes": ["config/rector-rules.php"]
}
}
}
The config file should be a plain Rector config fragment (imports/rule registrations), not a full standalone rector.php, so it composes cleanly inside the host project.
CI / Docker pattern. The generated file lives in vendor/, so it is rebuilt on every clean install. Ensure CI runs a normal composer install (not --no-scripts / --no-plugins) with allow-plugins configured, then vendor/bin/rector process --dry-run. A stale or absent generated file is a common "works locally, fails in CI" cause.
Verification pattern. After adding an extension, assert the generated file references it and that the expected rule classes appear:
composer dump-autoload -v # watch the plugin output
grep -R "<vendor>/<package>" vendor/rector/extension-installer/
vendor/bin/rector process --dry-run --debug
Migration pattern. When moving off the plugin, copy the generated import/require lines from the generated config into rector.php once, then remove the plugin. This keeps behaviour identical and avoids the generated-file dependency.
allow-plugins. The plugin simply does not run and extensions appear "not installed" to Rector. First debugging step is always composer diagnose plus a -v dump-autoload to confirm the plugin executed.post-autoload-dump. Adding an extension without a subsequent composer dump-autoload (or install/update) leaves Rector using the old rule list. If in doubt, dump and re-run.RectorConfig class and withSets()/withRules(); a 2021-era generated-config mechanism may not be loaded by modern Rector at all. Read the generated file and the Rector binary's config loading to confirm the include actually happens — do not assume.--no-dev production deploy. If you run Rector outside dev, move the plugin to require.rector.php import the same extension, rules can be registered twice. Usually harmless for idempotent rules, but it bloats --debug output and can cause surprising ordering. Audit rector.php when adopting the plugin.required packages. If two extensions override the same rule, the winner is not obvious — pin ordering by importing the conflicting extension manually in rector.php and removing it from the auto-discovery path.rector-extension (or lacks the extra.rector.includes entry) will be ignored without warning. Check composer show <package> and the package's composer.json.NOASSERTION. For commercial use, confirm terms from the source repository before depending on it; do not rely solely on the package metadata.import() lines in rector.php, using the plugin only if your extension list is large and churny.How can I help you explore Laravel packages today?