Laravel Pintは、PHPのコードスタイルを機械的に揃えるコマンドラインツールです。中身はPHP CS Fixerで、そこにLaravel流の既定ルールと薄いCLIをかぶせたものだと考えると構造がつかめます。新規のLaravelアプリには最初から入っているため、導入作業そのものはほぼ発生しません。判断が要るのはその先。どのプリセットを土台にするか、pint.jsonでどこまで手を入れるか、CIで整形するのか検査だけにとどめるのか、という三点です。この記事では v1.30.5(2026年8月10日公開)のソースと公式ドキュメントを実測しながら、設定と運用の決め方を整理します。
まとめ:既定プリセットのまま入れ、CIは検査だけに寄せる
結論を先に示す構成です。プリセットは既定の laravel のままで始め、rules での上書きは「チームで実際に議論になった項目だけ」に限ります。PHP CS Fixerには数百のルールがあり、pint.jsonを育てすぎると、そのファイル自体がレビュー対象になって本末転倒になります。
CIでの回し方は、整形結果をコミットで書き戻す方式より、--test で検査だけを行い差分があれば落とす方式を推します。書き戻し方式はbot経由のコミットがブランチ保護やレビュー承認の状態をリセットしやすく、pull requestの履歴も読みにくくなるためです。ローカル側では --dirty、pull requestでは --diff=origin/main を使い、対象を変更ファイルだけに絞ると、既存コードの巻き込み整形を避けられます。
入れ方の順序も決めておきます。数年分の履歴がある大きなコードベースへ、初回から全ファイルを一括整形して投入するのは避けるべきです。新規ファイルと変更ファイルだけを対象にし、既存部分は触らずに残す。この順序を守るかどうかで、導入後の一か月が静かに進むか、レビューの停滞を招くかが分かれます。
PHP CS FixerのラッパーとしてのLaravel Pintの守備範囲と導入経路
Pintの位置づけを取り違えると、静的解析ツールと役割が重複していると誤解しがちです。内部構造から確認します。
PHP CS Fixer 3.95系に依存するv1.30.5の内部構造
v1.30.5のcomposer.jsonを見ると、requireに入っているのは php: ^8.3.0 と ext-json、ext-mbstring、ext-tokenizer、ext-xml だけです。PHP CS Fixer(friendsofphp/php-cs-fixer ^3.95.18)はrequire-devに置かれ、配布されるPintのビルドへ取り込まれる形をとります。この構造には実務上の意味があります。プロジェクト側が別バージョンのPHP CS Fixerやその依存パッケージを使っていても、composerの依存解決がぶつかりにくい、という点です。
公式の説明は「ミニマリストのためのPHPコードスタイル修正ツール」で、実体はPHP CS Fixerのルールセットに名前を付け直した薄い層です。ルールの挙動そのものはPHP CS Fixer側の実装であり、細かく調べたいときの一次情報もそちらになります。なおPHPの下限は8.3で、8.2以下のプロジェクトでは最新版のPintを入れられません。
新規アプリへの同梱と既存プロジェクトへのcomposer導入手順
新規に作成したLaravelアプリにはPintが最初から含まれるため、./vendor/bin/pint を叩けばその場で動きます。既存プロジェクトへ後から入れる場合は composer require laravel/pint --dev の1行で終わります。引数なしで実行するとカレントディレクトリ以下のPHPファイルを走査して書き換えるので、初回は必ず作業ツリーをクリーンにしてから実行してください。
特定の範囲だけ整形したいなら、./vendor/bin/pint app/Models のようにディレクトリやファイルを引数で渡します。導入初日は、この引数付き実行で1ディレクトリだけ整形し、生成された差分の量と種類を目視してください。差分がレビュー可能な規模かどうかで、その後の展開方針が決まります。
PHPStan・Psalmとの守備範囲の切り分けと併用時の実行順序
Pintが直すのはスタイルだけで、バグは見つけません。未定義プロパティへのアクセスや型の不整合を検出するのはコードを実行せずにバグを検出するPHPStanの役割であり、両者は競合しません。CIに並べるときは、Pintの検査を先に置いてスタイル差分で早く落とし、その後にPHPStanやテストを走らせる順が扱いやすい構成です。整形で行番号が動いた状態で解析結果を読むと、指摘箇所の照合に余計な手間がかかります。
命名規則やディレクトリ構成の取り決めは、Pintでは強制できません。テーブル名やモデル名の単複、コントローラーの命名といった規約はLaravelの命名規則一覧の領域で、Pintが担うのは空白・改行・インポート順といった機械的に決着する形式面に限られます。この線引きをチームへ先に共有しておくと、「Pintを入れたのにコードの書き方が揃わない」という不満が出にくくなります。
laravel・psr12など5プリセットの違いとpint.jsonでのルール調整
設定ファイルを書く前に、土台となるプリセットを決めます。v1.30.5の同梱は5種類です。
laravel・per・psr12・symfony・emptyの選び分け基準
プリセットの実体は resources/presets 配下の5ファイルで、いずれもPHP CS Fixerのルール配列を返します。既定は laravel です。
| プリセット | 土台 | 選ぶ場面 |
|---|---|---|
| laravel(既定) | Laravel本体の慣習 | Laravelアプリ全般 |
| psr12 | PSR-12 | 規約準拠を明示したい場合 |
| per | PER Coding Style | PSR-12の後継に追随する場合 |
| symfony | Symfony流 | Symfony系の資産が多い場合 |
| empty | ルールなし | 全ルールを自前で組む場合 |
Laravelアプリなら laravel を選んで差し支えありません。社内の規約文書でPSR-12準拠をうたっている場合や、Laravel以外のPHPパッケージを同じ基準で扱いたい場合に psr12 を検討します。empty は土台を持たず、rulesに書いたものだけが適用されます。既存の .php-cs-fixer.dist.php をそのまま持ち込む移行期以外、最初から empty を選ぶ理由はありません。
rulesでの個別上書きとin・exclude・notPathによる対象絞り込み
pint.jsonはプロジェクトルートに置きます。ConfigurationJsonRepositoryが読むファイル探索系のキーは exclude、in、notPath、notName の4つで、in は v1.30.0(2026年7月28日)で加わりました。役割は次のとおり分かれています。
- in:走査対象を指定ディレクトリだけに限定する(v1.30.0以降)
- exclude:ディレクトリ単位で除外する
- notName:ファイル名のパターンで除外する
- notPath:個別のファイルパスを除外する
実務でまず使うのは exclude です。マイグレーション、生成コード、ベンダー由来のスタブなど、整形しても意味がない場所を落とすだけで差分をかなり減らせる仕組みです。rules は preset の上に重ねる差分指定で、simplified_null_return を true にする、array_indentation を false にする、といった粒度で書きます。ルール名はPHP CS Fixer側の名前がそのまま通り、Pint独自の Pint/phpdoc_type_annotations_only のようなカスタムルールも指定できます。
extendsとconfig指定で組織共通のpint.jsonを配る運用
複数のプロジェクトを同じ基準で回すなら、設定を1か所にまとめます。方法は2つ。ひとつは --config vendor/my-company/coding-style/pint.json のように外部の設定ファイルを直接指すやり方で、もうひとつは v1.23.0(2025年7月3日)で入った継承機能を使い、基底の設定ファイルを読み込んだうえでプロジェクト固有の差分だけをpint.jsonに書く方式です。
受託開発のように案件ごとにリポジトリが分かれる状況では、後者が扱いやすい構成です。共通ルールをcomposerパッケージとして配り、各案件は例外だけを数行書く。こうしておくと共通ルールの改定が全案件へ一度に届き、案件側の差分を読めば「なぜここだけ外したのか」も追えます。設定を丸ごとコピーして回す運用は、半年後に必ず食い違います。
–test・–dirty・–diffで組み立てるCI差分チェックの運用設計
Pintの価値はCIに置いたときに出ます。ただし置き方を間違えると、pull requestが常に汚れる原因になります。
–test・–repair・–bailの終了コードと使い分け基準
DefaultCommandが定義するオプションのうち、CIの設計に効くのは次の3つ。挙動が似て見えるので整理します。
| オプション | ファイル書き換え | 終了コード |
|---|---|---|
| –test | しない | 指摘があれば1 |
| –repair | する | 変更したら1 |
| –bail | しない(最初で停止) | 指摘があれば1 |
CIの検査ジョブに置くなら --test です。ファイルを触らずに指摘の一覧を出し、1件でもあれば終了コード1で落ちます。--repair は書き換えたうえで失敗扱いにするもので、Git hookのようにローカルで直しつつ気づかせたい場面に向きます。--bail は最初の指摘で打ち切るため、巨大なリポジトリでフィードバックを短くしたいときの選択肢。出力を後続処理へ渡すなら --format も使えます。
–dirtyと–diffでレビュー対象ファイルを絞る差分運用
既存プロジェクトへ後から入れる場合、全ファイル整形は現実的ではありません。対象を絞る手段が2つ用意されています。--dirty はGitでコミットされていない変更のみを対象にし、--diff=origin/main は指定ブランチから分岐して以降に変わったファイルだけを対象にします。v1.30.0からは --diff がリネームされたファイルも拾うようになりました。
運用の型はこうなります。ローカルのコミット前フックで pint --dirty、pull requestのCIで pint --test --diff=origin/main。この2段構えなら、触っていないファイルの整形差分がレビューに混ざりません。なおv1.30.4(2026年8月5日)で、Gitが使えない環境で --dirty や --diff を指定したときのエラーが表に出るよう修正されました。Dockerの薄いCIイメージにgitを入れ忘れると、以前は原因が分かりにくい形で止まっていた箇所です。
GitHub Actionsでの整形差分の自動コミットと失敗時の扱い
公式ドキュメントが載せているワークフロー例は、shivammathur/setup-php@v2 の tools に pint を指定してPint本体をセットアップし、実行後に stefanzweifel/git-auto-commit-action@v6 で整形結果を書き戻す構成です。ジョブの組み立てそのものはGitHub Actionsでビルド・自動テストを自動化する方法で扱っている基本形と変わりません。
ただし自動コミット方式には副作用があります。botのpushでレビュー承認がリセットされる、必須ステータスチェックが再実行される、fork元からのpull requestでは書き込み権限がなく失敗する、といった具合です。既定は検査のみ(--test)にして、整形はローカルとエディタ側に任せる。自動コミットは、手元の環境を揃えられないOSSのような場面に限るのが安全側の線引きです。
v1.30.0で入った–bladeオプションとNode常駐ワーカーの前提条件
PintはPHPファイルの整形ツールとして始まりましたが、2026年7月28日のv1.30.0でBladeテンプレートの整形が加わりました。実装まで踏み込んで確認します。
v1.30.0で追加されたPint/laravel_bladeルールの適用範囲
CLIには --blade というオプションが増えており、ヘルプには「Pint/laravel_blade ルールを有効にしてBladeファイルを整形する」と説明されています。既定では無効で、明示的に指定するか、pint.jsonのrulesで該当ルールを有効化したときだけ動作する設計です。BladeFormatter.php の初出コミットは2026年6月25日で、v1.29.3のツリーには存在せず、v1.30.0から含まれます。Bladeも整形したいなら、v1.30系以上への更新が前提です。
整形の中身は単純なインデント揃えにとどまりません。ソースを追うと、短い x-slot の1行への畳み戻し、scriptタグやstyleタグ内に埋まったBladeの退避と復元、Alpineの x-mask 属性値をJS式として壊さないための保護、@phpブロック内のPHPをPint本体で整形する処理、といった専用パスが並びます。Bladeに混在するHTML・PHP・JSを崩さずに扱うための実装です。
nodeワーカー起動が前提となるCI環境での事前セットアップ
ここが実務上の分岐点になります。Blade整形の中核はPHPではなくprettierで、Pintは同梱した resources/js/worker.cjs を node コマンドで起動し、標準入出力でファイル内容をやり取りします。ワーカーは無応答が30秒続くと破棄される設計です(WORKER_IDLE_TIMEOUT)。
つまり --blade を使うなら、実行環境にNode.jsが必要になります。PHPだけを入れた軽量なCIイメージで、PHPファイルの整形は通るのにBlade整形で止まる、という食い違いが起こりえます。CIでBladeまで対象にするなら、Nodeのセットアップ手順を先に足しておいてください。ローカル側でPHPとNodeをまとめて揃えるなら、Laravel Herdのバージョン管理と環境共有が選択肢になります。逆に、フロントをVueやReactで組んでいてBladeがレイアウト数枚しかないなら、--blade を入れずPHPだけを対象にする判断で構いません。得られる差分より、CI構成が増える負担のほうが大きくなります。
既存コードベースへの一括適用でPintを見送るべき条件と失敗パターン
Pintは導入コストがほぼゼロに見えますが、入れ方を誤ると開発速度を落とします。採用しない判断も含めて条件を示します。
初回の一括整形がGit履歴とレビュー効率を壊す場面と回避手順
数万行規模の既存コードへ全ファイル整形を一度に適用すると、そのコミット以降、git blame の結果がほぼ全行で整形コミットを指すようになります。障害調査で「この条件分岐を入れたのは誰か、どの案件か」を追う手がかりが一段遠のく、という実害が出ます。
回避の手順は決まっています。第一に、初回は --diff と --dirty で変更ファイルだけを対象にし、既存部分に触れないこと。第二に、全体を揃えたい場合は整形専用のコミットを1つだけ作り、そのハッシュを .git-blame-ignore-revs に登録してblameから外すこと。第三に、そのコミットにロジック変更を1行も混ぜないこと。整形と修正が同居すると、レビュー担当は数千行の差分から意味のある変更を探すはめになります。
実験段階のparallelオプションを本番CIに入れない判断基準
v1.23.0で --parallel(短縮形 -p)が入り、--max-processes でプロセス数を指定できるようになりました。指定しなければマシンのコア数ぶんが使われます。速度の改善幅は大きいものの、v1.30.5時点でもヘルプの説明に Experimental の語が残ったままです。
判断としては、ローカルでの手動実行や、失敗しても影響が閉じる場面では使ってよい。マージをブロックする必須チェックに入れるのは見送るべきです。実験扱いのオプションが原因で不安定に落ちるCIは、チームがチェック結果を信用しなくなる方向に働きます。Pintの検査は数十秒で終わることが多く、そこを短縮する見返りは、必須チェックの信頼性を賭けるほど大きくありません。
整形ルールの定着を保守運用フェーズで維持するための社内体制条件
Pintを入れて数か月経つと、pint.jsonのrulesが誰も説明できない状態で膨らんでいることがあります。原因は決まっていて、「レビューで指摘されたから外した」「特定のファイルだけ通らなかったから除外した」という個別対応が記録なしに積み上がるためです。rulesとexcludeを触るpull requestには、理由をコミットメッセージに残す運用を最初から義務づけてください。
もうひとつ、Pintのバージョン更新も体制面の課題です。v1.30系は2026年7月28日から8月10日までの2週間で5回リリースされており、更新のたびに整形結果が微妙に変わる可能性があります。Dependabotなどで自動更新している場合、更新pull requestに全ファイル整形の差分が混ざる可能性を織り込んでおく必要があるでしょう。この種の継続的な手入れを社内だけで抱えきれない場合は、保守運用・内製化支援のように開発体制ごと相談できる外部と組む選択肢もあります。ツールの導入自体は1コマンドで終わりますが、維持は人の運用に戻ってくる作業です。
よくある質問
導入時に検索されやすい疑問を、v1.30.5時点の実装をもとにまとめます。
Laravel PintとPHP CS Fixerはどちらを使うべきですか?
Laravelアプリなら通常はPintで足ります。PintはPHP CS Fixerを内包しつつ、設定ファイルをPHPスクリプトではなくpint.jsonというJSONに簡素化したものだからです。PHP CS Fixerを直接使う理由が残るのは、Finderに複雑な条件を書きたい場合、PHP 8.2以下のプロジェクトで最新のPintを入れられない場合、Laravel以外のフレームワークで既存の .php-cs-fixer.dist.php が十分に育っている場合に限られます。
pint.jsonでPSR-12に準拠させるにはどう書きますか?
プロジェクトルートのpint.jsonで preset キーに psr12 を指定すれば、土台がPSR-12のルールセットに切り替わります。コマンドラインから一時的に切り替えるなら --preset psr12 でも同じ結果になります。PSR-12の後継として策定されたPER Coding Styleに合わせたい場合は per を指定してください。どちらを選んでも、rulesキーで個別のルールを上書きする書き方は変わりません。
Laravel Pintは特定のディレクトリだけ整形できますか?
特定ディレクトリだけの整形も可能です。方法は2つあり、実行時に ./vendor/bin/pint app/Http のようにパスを引数で渡すか、pint.jsonの in キーで走査対象そのものを絞ります。in は v1.30.0 で追加されたキーなので、それ以前のバージョンでは exclude や notPath で不要な場所を落とす書き方です。CIとローカルで対象がずれると混乱するため、恒久的な絞り込みは設定ファイル側へ寄せるほうが管理しやすくなります。
Pintの実行結果をCIで失敗させるにはどのオプションですか?
実行時に --test を付けます。ファイルを書き換えずに検査だけを行い、スタイルの指摘が1件でもあれば終了コード1で終わるため、そのままCIの失敗として扱える仕組みです。ファイルを直したうえで失敗させたいなら --repair、最初の指摘で即座に打ち切りたいなら --bail を選びます。pull requestで変更分だけを見るなら --test --diff=origin/main の組み合わせになります。
Laravel PintはBladeファイルも整形してくれますか?
v1.30.0以降であれば --blade オプションで整形できます。既定では無効なので、指定しない限りBladeファイルは対象外です。ひとつ注意点があり、Blade整形はPintに同梱されたprettierワーカーをnodeコマンドで起動する実装のため、実行環境にNode.jsが入っている必要があります。PHPのみのCIコンテナではこの段階で失敗するので、Bladeまで対象にするならNodeのセットアップを先に足してください。
関連記事
- Laravelの命名規則一覧|テーブル・モデル・規約と自動チェックまで:Pintでは強制できない命名とディレクトリ構成の取り決めを扱っています。
- PsalmとPHPStanの違いを比較|PHP静的解析ツールの選び方【2026年時点】:Pintと並べて置く静的解析ツールの選定基準が分かります。
- Laravel Debugbarの使い方|導入・APP_DEBUG設定・SQL確認とv4対応:開発時の調査を担うもう一方の開発用パッケージです。
- Laravelのキャッシュクリア|cache:clearとoptimize:clearの違いと本番デプロイの手順:CIの後段に置くデプロイ手順の組み立てを確認できます。