Laravel + React Starter Kit を Docker で検証して改良した fork を公開
公式の laravel/react-starter-kit(Inertia + React 19 + shadcn/ui + Fortify)を Docker Desktop で動かし、本番運用に耐える形に書き直したフォークを公開する。テストは公式版の 40 passed をベースに 44 passed / 151 assertions まで増加。本記事は React / Inertia 固有の論点に絞って記録する。
検証環境
- PHP 8.5.5
- Laravel 13.5.0
- Composer 2.9.7
- Node 22.22.2
- npm 10.9.7
- Database SQLite (tests)
- OS Docker Desktop (php:8.5-cli-bookworm)
Laravel + React Starter Kit を Docker で検証して改良した fork を公開
公式の laravel/react-starter-kit(Inertia + React 19 + shadcn/ui + Fortify)を Docker Desktop で動かし、本番運用に耐える形に書き直したフォークを公開する。テストは公式版の 40 passed をベースに 44 passed / 151 assertions まで増加。本記事は React / Inertia 固有の論点に絞って記録する。
backend 側の改修(.env.example / timezone / セキュリティヘッダ / HTTPS 強制 / レート制限 / 認証ログ)は React・Vue・Livewire の 3 fork で完全に同一なので、pillar 記事に集約した:
→ Laravel スターターキット共通 backend を本番化する 6 つの改修
本記事はその cluster(枝)として、React Starter Kit に固有の話だけを扱う。
対象の公式サンプル
| 項目 | 値 |
|---|---|
| 名前 | Laravel + React Starter Kit |
| 公式 URL | https://github.com/laravel/react-starter-kit |
| 改良版 fork | https://github.com/codelift-dev/react-starter-kit/tree/improvements |
| スタック | Laravel 13 + Inertia + React 19 + TypeScript + shadcn/ui + Fortify |
| 元 / 改良版ライセンス | MIT / MIT |
| 検証日 | 2026-04-19 |
| 上流 commit | laravel/react-starter-kit@2e22614 |
検証環境
pillar 記事と共通(Docker Desktop、PHP 8.5.5 / Laravel 13.x / Node 22.22.2)。再現は fork の codelift/Dockerfile + codelift/docker-compose.yml で行える。
git clone https://github.com/codelift-dev/react-starter-kit.git
cd react-starter-kit
git checkout improvements
docker compose -f codelift/docker-compose.yml build
docker compose -f codelift/docker-compose.yml run --rm app
React Starter Kit 固有の論点
A. composer install 前に npm run build するとビルドが不可解に失敗する
これは React / Vue 版に固有(Livewire 版にはない)。
症状: clone 直後に npm run build を先に走らせると、Vite ビルドが次のエラーで落ちる。
require(.../vendor/autoload.php): Failed to open stream: No such file or directory
in artisan on line 10
原因: vite.config.ts の @laravel/vite-plugin-wayfinder プラグインが、ビルド中に php artisan wayfinder:generate を shell out する。Wayfinder は Laravel のルート定義から TypeScript の型付きルートヘルパーを生成する仕組みで、ビルド時に artisan を起動する。Composer 依存が未インストールだと artisan が vendor/autoload.php を読めずに落ちる。
なぜ厄介か: エラーメッセージに composer install の文字が一切出ない。初見の開発者は Vite か Wayfinder のバグを疑い、見当違いの方向に時間を溶かす。vendor/autoload.php というパスから「Composer をまだ流していない」と即座に気付けるのは、Laravel に慣れた人だけ。
改修: README に Setup セクションを追加し、composer install → npm run build の順を明示。Wayfinder がビルド時に artisan を呼ぶ事実も併記して、なぜこの順序なのかを理解できるようにした。
React 19 + Inertia の初期 state と CSP
React Starter Kit は React 19 を使う。Inertia はサーバー側ルーティング + React コンポーネントを繋ぐ仕組みで、ページ遷移ごとにサーバーが JSON の「page object」を返し、React がそれを描画する。
問題は初回ロード。Inertia は初回 HTML に、ページコンポーネントと初期 props を埋め込む必要がある。これは <div id="app" data-page="{...エンコードされた props...}"> という形で root 要素の属性に入り、@inertia Blade ディレクティブが出力する。
この「初期 props を HTML に直接埋める」設計が、Content-Security-Policy を厳格化するときの障壁になる。'unsafe-inline' を完全に外して nonce ベースに移行するには、Inertia のレスポンスレンダリング(HandleInertiaRequests ミドルウェアや Inertia のレスポンスクラス)に手を入れて nonce を通す必要がある。
CodeLift の改良版では、CSP 自体は導入する(pillar 記事 finding D)が、script-src に 'unsafe-inline' を残す保守的な設定にとどめた。nonce 化は Inertia 側の改造を伴う独立テーマなので、別途 follow-up で扱う予定。
参考までに、Inertia を使わない Livewire 版では初期 state を inline script に埋めないため、'unsafe-inline' を外した nonce ベース CSP に移行できる。その手法は Livewire の CSP nonce 化記事に詳しい。
J. 設定エンドポイントのレート制限が password だけ
React Starter Kit の routes/settings.php は、明示的な throttle ミドルウェアを password 更新ルートにしか付けていない。
Route::patch('settings/profile', ...)->name('profile.update'); // throttle なし
Route::delete('settings/profile', ...)->name('profile.destroy'); // throttle なし
Route::put('settings/password', ...)->middleware('throttle:6,1')...; // throttle あり
セッションが乗っ取られた場合、profile の連続書き換えやアカウント連続削除試行が、グローバルデフォルトの範囲で通ってしまう。
改修: React/Vue 版は設定変更が PATCH / DELETE という HTTP verb で素直に表現されているので、ルート定義に throttle ミドルウェアを足すだけで済む。
- Route::patch('settings/profile', ...)->name('profile.update');
+ Route::patch('settings/profile', ...)->middleware('throttle:10,1')->name('profile.update');
- Route::delete('settings/profile', ...)->name('profile.destroy');
+ Route::delete('settings/profile', ...)->middleware('throttle:3,1')->name('profile.destroy');
アカウント削除は terminal な操作なので 3 回 / 分と厳しめに絞った。(Livewire 版は Route::livewire 経由でコンポーネント内 AJAX なので、この修正がそのまま使えない — 詳細は Livewire 記事を参照。)
改良版の commit 構成
improvements ブランチに 8 commits:
| commit | finding | 出典 |
|---|---|---|
| README Setup | A(React/Vue 固有) | 本記事 |
.env.example コメント |
B | pillar |
| timezone env 化 | C | pillar |
URL::forceScheme |
E | pillar |
SetSecurityHeaders middleware + test |
D | pillar |
| login rate limiter 2 段化 | G | pillar |
auth log channel + subscriber + test |
I | pillar |
| settings throttle | J(本記事) | 本記事 |
テストは公式版 40 passed → 改良版 44 passed / 151 assertions(SecurityHeaders 2 件・AuthLogging 2 件を追加、既存は全 pass)。
before / after(React 固有部分)
| 観点 | 公式版 | 改良版 |
|---|---|---|
php artisan test |
40 passed / 136 assertions | 44 passed / 151 assertions |
| ビルド順序のドキュメント | なし(Wayfinder の落とし穴あり) | README に明記 |
| settings endpoints の throttle | password のみ | profile update / destroy にも |
共通 backend 改修(6 件)の before / after は pillar 記事を参照。
どのケースで向くか
laravel/react-starter-kitをテンプレに本番プロダクトを立ち上げる予定で、最初に足回りを固めたい- React / Vue / Livewire のどれにするか検討中で、React を選んだ場合の production 化コストを把握したい → 結論は3 種比較記事に整理した(backend 改修コストは 3 つとも同じ)
再現と取り込み
git clone https://github.com/codelift-dev/react-starter-kit.git
cd react-starter-kit
git diff main improvements -- . ':!codelift'
各 commit は独立、cherry-pick 可能。
関連記事
- pillar: Laravel スターターキット共通 backend を本番化する 6 つの改修
- 姉妹 cluster: Vue 版 / Livewire 版
- 比較: React / Vue / Livewire 比較
ライセンス
元サンプル / 改良版とも MIT。検証結果は検証日時点のもの。
この記事を含む比較
関連記事
- Laravel + Vue Starter Kit を Docker で検証して改良した fork を公開 公式の laravel/vue-starter-kit(Inertia + Vue 3 + shadcn-vue + Fortify)を Docker で動かし、本番運用に耐える形に書き直したフォークを公開する。テストは 40 passed → 44 passed / 151 assertions。本記事は Vue / Inertia 固有の論点に絞る。
- Laravel + Livewire Starter Kit を Docker で検証して改良した fork を公開 公式の laravel/livewire-starter-kit(Livewire v4 + Flux + Alpine)を Docker で動かし、本番運用に耐える形に書き直したフォークを公開する。テストは公式版の 33 passed をベースに 37 passed / 92 assertions。本記事は Livewire 固有の論点に絞る — 3 つのスターターキットの中で Livewire は最も backend 以外の差分が大きい。
- Laravel スターターキット共通 backend を本番化する 6 つの改修 Laravel 公式のスターターキット(React / Vue / Livewire)は、フロントエンド層こそ違うものの backend は同一の Laravel + Fortify コード を共有している。そのため、本番運用に向けた hardening も 3 つで共通する部分が大半を占める。本記事はその共通部分 — CodeLift が 3 つの fork すべてに適用した backend 改修 — を 1 か所にまとめた pillar(土台)記事である。