Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Rector Config Laravel Package

wyrihaximus/rector-config

RectorPHP configuration tooling with additional rules. Provides a RectorConfig with sensible defaults for etc, examples, src, and tests directories, and converts supported doc tags to attributes. Install as a dev dependency via Composer.

View on GitHub
Deep Wiki
Context7

Getting Started

This is not a Laravel package. It is a shared RectorPHP configuration plus extra rules, published as a dev dependency. You get value from it the same way you get value from a shared PHPStan or Pint config: you stop hand-maintaining a ruleset and inherit someone else's curated one.

Install alongside Rector itself:

composer require --dev rector/rector wyrihaximus/rector-config

Then look at the vendor directory before writing any config. The two things you need are the set class or config file the package exposes, and the list of rules it registers:

ls vendor/wyrihaximus/rector-config
cat vendor/wyrihaximus/rector-config/README.md
ls vendor/wyrihaximus/rector-config/src

The package's readme is the source of truth for the exact class name. Wire it into a root rector.php next to Rector's own sets, since a Laravel app still needs the PHP version set and the Laravel set to be useful:

<?php

use Rector\Config\RectorConfig;

return RectorConfig::configure()
    ->withPaths([__DIR__ . '/app', __DIR__ . '/database', __DIR__ . '/tests'])
    ->withSets([
        // confirm the exact class from the package readme
        \WyriHaximus\Rector\Set\ValueObject\SetList::ALL,
        \Rector\Laravel\Set\LaravelSetList::LARAVEL_110,
    ]);

Your first use case should be narrow and reversible: pick one legacy directory, dry-run it, and read the diff like a pull request.

vendor/bin/rector process app/Support --dry-run

If that diff is reasonable, run it for real on a branch, commit the mechanical changes on their own, and only then widen the paths. Adopting Rector by running it repo-wide on day one produces a diff nobody can review, which is the single most common way teams abandon the tool.

Implementation Patterns

Layer, do not replace. Treat the package set as one input among several. PHP version set, Laravel set, dead-code set, your own house rules. Keep the ordering explicit and comment why each entry is there so the next developer can delete the right one.

Ratchet instead of boiling the ocean. Keep legacy code excluded and shrink the exclusion list over time. New code is held to the stricter standard from the moment it lands:

->withSkip([
    \Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationRector::class => [
        __DIR__ . '/app/Legacy',
    ],
])

Gate CI on dry-run, scoped to changed files. Rector has no native "only changed" flag, so most Laravel teams pipe a diff. This keeps the CI step fast and keeps failures attributable to the author who caused them:

vendor/bin/rector process --dry-run $(git diff --name-only origin/main... | grep '\.php$' | tr '\n' ' ')

Run it in a fixed order in your pipeline. Rector rewrites structure, Pint rewrites style. Running Pint first means Rector invalidates formatting; running Rector first then Pint gives you a clean final tree. Add both as composer scripts so the order lives in one place:

"scripts": {
  "rector": "rector process --dry-run",
  "rector:fix": "rector process",
  "lint": ["@rector:fix", "pint"]
}

Bisect with single rules, not whole sets. When a set produces an unwanted rewrite, copy the specific rule out of the set and enable rules one at a time on a scratch branch. Rector applies rules in a pipeline, so a two-rule interaction can produce output neither rule produces alone. -vvv on process shows you which rule touched which file.

Pair the config package with the extra rules, or do not bother. Additional rules are ordinary Rector rules. You are not obliged to take the whole set: register only the rules you actually want, and skip the rest by class name. This is the extension point that matters, because the author's style opinions are likely stronger than your team's.

Treat it as a contribution target too. agents/AGENTS.md in the repo documents a make-driven workflow (make install, make contrib, make unit-testing-filter, make before handing back) with a hard QA bar: 100% coverage, 100% MSI from Infection, 100% type coverage. If you find a rule that misfires on Laravel idioms and want to fix it upstream, expect to write dataprovider-driven tests that clear all three bars. That is a real cost and should factor into "fork or contribute".

Gotchas and Tips

Pin it. A config package changes your code output when it changes its rule list. A routine composer update can turn into a surprise mega-diff across every PR. Pin the version and upgrade deliberately, reading the package's diff in composer.lock output before merging.

Bus factor is one, and adoption is zero. Zero stars and zero dependents means no community pressure to preserve backwards compatibility and no crowd-sourced bug reports for Laravel-specific edge cases. If a rule is load-bearing for your codebase, inline the rule class list into your own rector.php so a package release cannot silently change your build. The escape hatch is cheap; use it without guilt.

Expect friction with Laravel magic. Facades, __get/__set on models, macros, container string resolution, and Blade-adjacent helper files confuse rules that reason statically. Dead-code and return-type rules are the usual offenders. Whenever you see a rule "fixing" a model accessor or a facade call, skip that rule for that path rather than disabling it globally.

Do not let it touch generated or vendored code. vendor/, storage/, bootstrap/cache/, and anything compiled must stay out of withPaths. A rule that rewrites a compiled file produces failures that look like framework bugs.

Config is executable PHP. Importing the set means vendor code runs at config load time. Normal for Rector, but it means a broken package release breaks your lint step before any rule runs. Keep the config importable in isolation (php rector.php should not fatal) so the failure mode is obvious.

Cache and memory. Rector caches aggressively. After changing rector.php, run with --clear-cache or you will spend twenty minutes wondering why a removed rule still fires. Gitignore rector_cache (or wherever your version writes it), and set --memory-limit on large codebases, since parallel workers multiply memory rather than sharing it.

Skip rules by class, not by name string. Typos in a rule class name in withSkip fail silently. A rule you believe is disabled keeps rewriting files, and you blame the package. Reference RuleClass::class so a renamed class becomes a fatal error instead of a silent no-op.

The make toolchain is for upstream, not for you. agents/AGENTS.md describes the author's container-based development flow, including prohibitions on direct docker and cd usage. None of that applies to consuming the package in a Laravel app. Do not import those instructions into your own project; taking the config file is the whole integration surface.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums