rector/rector-doctrine
Rector Doctrine provides Rector rules to automate refactoring and upgrading Doctrine ORM/DBAL code in PHP projects. It helps modernize annotations, mappings, queries, and legacy APIs with safe, repeatable code transformations.
Architecture fit. rector/rector-doctrine is not a runtime library — it is a rule pack that plugs into rector/rector as a dev-only dependency and participates in the build/CI layer rather than the application architecture. That makes it architecturally low-risk: it never ships to production, adds no runtime surface area, and its removal is a one-line composer remove --dev. For a team already running Rector, the fit is essentially free; for a team that does not run Rector, this package is not adoptable in isolation because it has no entry point of its own. The realistic positioning is "an accelerator inside an existing upgrade factory," not a standalone capability.
Integration feasibility. Mechanically trivial: composer require --dev rector/rector-doctrine, then reference the shipped sets from rector.php (annotation-to-attribute conversion, Doctrine version-targeted rewrites, and code-quality rules over entities, repositories, and collection usage). The real feasibility question is review capacity, not installation. Automated rewrites of mapping metadata are the class of change where "it compiles" is a weak signal — a wrong #[ORM\Column] attribute or a subtly altered association mapping yields a valid PHP file with a broken persistence model. Integration must therefore be paired with a semantic gate (doctrine:schema:validate, schema diff against a known-good database, integration tests against a real engine), not just a green CI build.
Technical risk. Blast radius is small; correctness risk is moderate and concentrated:
rectorphp org), but the numbers mean you should plan for the possibility of forking rather than assuming upstream responsiveness.Key questions to answer before committing.
phpstan-doctrine and our existing static analysis — overlapping rules, conflicting fixes, or complementary?Stack fit. Suitable for any Laravel/PHP service on Doctrine ORM or ODM where Rector is already or can be introduced as a dev dependency. Laravel shops running Eloquent get no value here; this is specifically for the Doctrine-backed portions of the estate (common in legacy modules, DDD-style bounded contexts, or Symfony-adjacent services inside a larger PHP portfolio). Confirm the actual Doctrine footprint first — the addressable surface is often a handful of modules rather than the whole monolith.
Migration path. Three credible entry points, in increasing ambition:
Starting at (1) to generate evidence, then deciding between (2) and (3), is the right sequencing. Do not open with a monolith-wide apply.
Compatibility and sequencing. Order matters more than configuration:
doctrine:schema:validate in CI, and a schema-diff check against a reference database.--dry-run on the whole codebase to size the diff, segmented by rule set — this produces the actual coverage number you were guessing at.Sequencing constraint to respect: do not run this concurrently with a framework major upgrade. Two simultaneous automated rewrite streams make regressions unattributable and turn bisection into guesswork.
Maintenance. A dev-only dependency with a narrow, well-understood failure surface — but it is a build-tool dependency, meaning breakage blocks CI rather than production. Pin exact versions, keep it out of the runtime lockfile path, and schedule a deliberate review each time Rector or Doctrine majors move. The fork contingency should be documented, not improvised; a one-page "how we'd take this in-house" note is cheap insurance against a stalled upstream.
Support. No commercial support, no SLA. Community issues on a low-traffic repository — expect days-to-weeks, and expect to solve edge cases yourself. Treat vendor responsiveness as best-effort and plan the upgrade calendar around our capacity, not upstream's release cadence.
Scaling. Two dimensions:
Failure modes to instrument.
| Failure | Detection | Mitigation |
|---|---|---|
| Silent semantic change in mapping | Schema diff vs. reference DB | Mandatory schema-diff gate; human sign-off on entity files |
| Partial rewrite / unhandled syntax | Rector crash or skipped file | Per-module runs; coverage report; manual tail backlog |
| Version incompatibility after bump | CI failure at tool level | Exact version pinning; upgrade in an isolated branch first |
| Divergent output across Rector versions | Diff churn on re-run | Freeze Rector version for the duration of an upgrade program |
| Reviewer fatigue → rubber-stamping | Rising defect rate post-merge | Cap batch size; never merge a rewrite batch without integration coverage |
Ramp-up. Low for anyone who has used Rector (config-driven, familiar --dry-run / --dry-run --diff workflow, maybe half a day). The non-obvious cost is Doctrine mapping literacy on the review side: an engineer who can run Rector is not automatically qualified to approve an association-mapping rewrite. Identify that reviewer before the first batch, not after.
Bottom line for a TPM. Low-risk, narrow-value tool that is worth adopting if and only if you are already running Rector and have a Doctrine upgrade on the roadmap. The 2.38 score and thin adoption are not disqualifying — the blast radius is genuinely small and MIT licensing makes exit cheap — but they do argue against making it a load-bearing part of a migration commitment. Position it as a productivity accelerant inside a human-supervised upgrade playbook, with the schema-diff gate and a named mapping reviewer as non-negotiable prerequisites. Fund it at the scale of a pilot on one module to generate a real coverage number before committing team capacity to a broader program.
How can I help you explore Laravel packages today?