matt-allan/laravel-code-style
Automatic code style checking and fixing for Laravel projects. Wraps PHP-CS-Fixer with Laravel-specific rules and presets, so you can enforce consistent formatting across your app, packages, and tests with a single command.
Install the package as a dev dependency and run the formatter once across a throwaway branch to see what it changes:
composer require --dev matt-allan/laravel-code-style
php artisan code:format
Look at these three places first:
php artisan vendor:publish (pick the code-style/laravel-code-style tag from the list) and inspect config/code-style.php. This is where paths and rule customizations live.php-cs-fixer. Read the rules before overriding them; most teams should accept the preset wholesale and only add project-specific exclusions.composer.json scripts — wire the command in immediately so nobody has to remember the artisan invocation:"scripts": {
"format": "php artisan code:format",
"format:check": "php artisan code:format --dry-run"
}
Your first real use case should be a formatting-only commit: run the formatter on the whole app/, tests/, config/, and database/ directories, commit that alone, and add the SHA to .git-blame-ignore-revs. Doing this before adding the check to CI prevents a giant noisy diff from landing alongside a feature branch.
Composer-script workflow. Treat composer format as the developer-facing entry point and composer format:check as the CI-facing one. Developers run the former before pushing; CI runs the latter. This keeps the artisan command an implementation detail.
CI gate. Add a job that runs the dry-run mode and relies on the non-zero exit code to fail the build. Keep it in the same workflow as tests so a formatting failure is visible next to a test failure, not buried in a separate pipeline:
- run: composer install --no-interaction --prefer-dist
- run: composer format:check
Pre-commit hook. A lightweight .git/hooks/pre-commit (or Husky/captainhook) that formats only staged PHP files keeps the main branch clean without forcing full-repo runs. Pass explicit paths to the command rather than formatting everything on each commit — the tool accepts path arguments, so php artisan code:format app/Http/Controllers is a normal pattern.
Scoped runs during refactors. When touching a legacy module, format just that directory (php artisan code:format app/Legacy) so reviewers can reason about the diff. Full-repo formatting during an active feature branch is the most common source of merge conflicts.
Per-directory conventions. If some directories need different rules (e.g. stricter rules for app/, looser for tests/), use the config to define path-scoped finder entries rather than maintaining a second config file or a separate tool.
Editor integration. Point a PhpStorm File Watcher or a VS Code "run on save" task at vendor/bin/php-cs-fixer fix --config=vendor/matt-allan/laravel-code-style/... — or, more simply, at php artisan code:format <current file>. The latter is more resilient to the package's internal config path changing.
Onboarding step. Put composer format in the README's "after cloning" block alongside composer install and php artisan migrate. New contributors otherwise discover the formatter only after their first CI red build.
The package is archived. This is the single most important fact day-to-day. It will not receive PHP version bumps or php-cs-fixer compatibility fixes. If you are starting a new Laravel project, use Laravel Pint instead — it is the first-party successor with the same underlying engine. Keep this package only where it is already working, and plan a migration when you next bump PHP or php-cs-fixer.
Pin your php-cs-fixer version. Because the package wraps an external fixer, a composer update that bumps php-cs-fixer across a major version can silently change rule behavior and produce a huge unexpected diff. Constrain friendsofphp/php-cs-fixer in composer.json and upgrade it deliberately.
Do not install it alongside Pint. Both register formatter commands and both ship presets; running one after the other produces churn and confusing CI failures. Pick one, and remove the other's dependency and config.
Dry-run exit codes matter. Confirm the dry-run/test flag your installed version supports with php artisan code:format --help before wiring CI. Some versions return 0 even when files would change unless the correct flag is passed — a green build that never actually checks anything is a classic failure mode here.
Exclude vendor/, storage/, bootstrap/cache/, and generated files. Formatting generated or third-party code creates diffs you cannot control and slows runs substantially. Add exclusions in the config, not via .gitignore (the formatter does not read it).
Config caching. If you run php artisan config:cache in local or CI environments, config edits to config/code-style.php are ignored until you php artisan config:clear. This is the usual cause of "my rule change did nothing."
Add the bulk-format commit to .git-blame-ignore-revs. Without it, git blame on every touched line points at the formatting commit, which is a real day-to-day annoyance for years afterward. Also configure git config blame.ignoreRevsFile .git-blame-ignore-revs for local use.
Memory and time limits. Formatting a large repo in one process can hit PHP's memory limit. Run per-directory, or raise memory_limit for the command in CI. If it dies mid-run, you get a partially formatted tree — rerun to completion before committing.
Extension points. Custom rules go through the config's fixer list (or a custom ruleset passed to php-cs-fixer), not by editing vendor files. If you need something the preset does not cover, add the fixer class name to the rules array and document why it deviates from the Laravel default, so future maintainers do not "clean it up."
Treat it as a lint step, not a code-quality step. The formatter does not replace PHPStan/Larastan or static analysis; teams that conflate the two often drop static analysis when they adopt formatting.
How can I help you explore Laravel packages today?