romanzipp/php-cs-fixer-config
A reusable PHP-CS-Fixer configuration from romanzipp for enforcing consistent coding standards across PHP projects. It provides opinionated rules and a simple setup for composer-based workflows, helping teams keep formatting predictable and reduce style-related review noise.
Architecture fit. Unchanged. romanzipp/php-cs-fixer-config is a dev-only tooling artifact — a curated PHP-CS-Fixer ruleset wired into a consuming project's .php-cs-fixer.php. It remains framework-agnostic with no service provider, no config publishing, no HTTP or DB surface, and no runtime footprint. It still occupies the same slot as Laravel Pint (which bundles PHP-CS-Fixer and a Laravel-blessed preset), so the architectural question is unchanged: which single enforcement layer owns style in this repo?
Integration feasibility. Mechanically still trivial (one composer require --dev, ~three lines of config), but the 3.0.0 release introduces a new mechanical constraint: the package now explicitly targets PHP-CS-Fixer v3.0. That is not a neutral statement — it means Composer must resolve this package's fixer constraint against whatever fixer version Pint already pulls in transitively. If the package requires ^3.0 and the project's Pint pins a later 3.x, resolution usually succeeds but rule behavior is unverified; if the project is still on fixer v2 anywhere, 3.0.0 is a hard blocker and the old major is the only option. This is the first time the package has had a real dependency-resolution conversation with a modern Laravel stack.
Technical risk. Materially re-rated, but not cleared:
Key questions. What is the exact php-cs-fixer/shim/friendsofphp/php-cs-fixer constraint in 3.0.0's composer.json, and does it conflict with the fixer version Pint resolves? What changed in the ruleset between 2.x and 3.x, or was this purely an API/namespace port? Which ruleset baseline does it extend (@PSR12, @Symfony, custom)? Is the config a class, a function, or a raw array? Is there a CHANGELOG or only the one-line release note? Does 3.0.0 declare a minimum PHP version? Who owns the ruleset if our conventions diverge? Migration cost if the package dies: near zero — which remains the finding.
Stack fit. Still poor-to-neutral as a dependency, still good as source material. A modern Laravel repo has Pint in require-dev; adding raw PHP-CS-Fixer plus a third-party personal preset creates two formatters, overlapping CI jobs, and inconsistent pre-commit hooks. The 3.0.0 release does not change this — it only makes the preset newer, not differently positioned.
Recommended path: vendor, don't depend. Unchanged and now stronger, because 3.0.0 gives you a fresher, fixer-v3-shaped ruleset to copy from. Lift the rules into tools/php-cs-fixer/rules.php or translate into a pint.json preset. You capture the v3 compatibility work and shed the abandonment and version-conflict risk. MIT makes this unambiguous.
Alternative path: direct dependency. Only if the team explicitly wants this author's exact conventions. Then: require ^3.0 only, pin the fixer version, confirm composer why friendsofphp/php-cs-fixer shows a single resolution path shared with Pint, and add a Renovate/Dependabot rule so a fixer major cannot land unreviewed. Note that 3.0.0 is the first version where this path is even coherent on a fixer-v3 stack — and the first where a Pint collision is plausible.
Compatibility. Verify 3.0.0's fixer constraint against the project's resolved fixer version before anything else; a Composer conflict here ends the evaluation. Then run the ruleset --dry-run --diff against current Pint output. Because the release targets fixer v3.0 specifically, audit for rules that were renamed or deprecated between v3.0 and the project's actual fixer version rather than trusting a clean run.
Sequencing.
composer.json constraint and diff its ruleset against the 2.x version; confirm it is a port, not a rules change.--dry-run --diff on a throwaway branch against the project's actual fixer version; diff against current Pint results to quantify churn and surface silent no-ops.--set-baseline if the diff is large, to avoid a mass-reformat PR blocking the team.--dry-run --diff as a required check) and the pre-commit hook in the same PR.Maintenance. Vendoring still means owning ~50 lines of JSON/PHP plus the fixer-v3 port that 3.0.0 just performed for you. Depending means inheriting a component whose demonstrated cadence is one release per several years. Either way, recurring cost is one fixer major upgrade every 12–18 months — and 3.0.0 is precisely that cost being paid upstream, which is the release's real value.
Support. Effectively none. Single maintainer, no SLA, no security policy, and now a one-line release note as the entire communication surface. Acceptable only because blast radius is CI formatting, not production.
Scaling. Compute cost unchanged (seconds, linear in file count, parallelizable). The organizational scaling argument is unchanged and mildly reinforced: a package that surfaces a breaking major with no migration guide is a poor thing to have declared independently across many repos. A vendored internal config or monorepo-shared preset scales better.
Failure modes.
--dry-run --diff smoke test on a known-bad fixture.Config construction; CI fails loudly, the good case.Ramp-up. Near zero technically for any PHP developer. The non-trivial ramp remains social: accepting an externally authored style contract, and getting reviewers to stop re-litigating formatting once it is enforced. The 3.0.0 release slightly helps here — a version that names its fixer target is easier to defend in an architecture review than a four-year-stale one.
TPM verdict. The release warrants a re-rating, not a reversal. It retires the literal "abandoned since 2021" objection and partially restores the compatibility contract, which should nudge the prior score (0.055 / 33.2 opportunity) upward — but one release, targeting a fixer version already several years old, communicated in a single sentence with no changelog or migration guidance, is not a maintenance commitment. The decision stands: treat 3.0.0 as the best version of this ruleset to harvest, vendor the rules internally, and enforce through the formatter Laravel already ships. Do not add a personal config as a long-lived dependency on the strength of one catch-up release.
How can I help you explore Laravel packages today?