Laravel + Livewire Starter Kit: Docker-verified fork
We took the official laravel/livewire-starter-kit (Livewire v4 + Flux + Alpine), ran it inside Docker, and published a production-hardened fork with the complete diff on GitHub. Upstream starts at 33 passed; the improved branch reaches 37 …
Verification environment
- PHP 8.5.5
- Laravel 13.x
- Composer 2.9.7
- Node 22.22.2
- npm 10.9.7
- Frontend Livewire v4 + Flux + Alpine
- Database SQLite (tests)
- OS Docker Desktop (php:8.5-cli-bookworm)
Laravel + Livewire Starter Kit: Docker-verified fork
We took the official laravel/livewire-starter-kit (Livewire v4 + Flux + Alpine), ran it inside Docker, and published a production-hardened fork with the complete diff on GitHub. Upstream starts at 33 passed; the improved branch reaches 37 passed / 92 assertions, added across 7 commits. The Livewire variant has a different finding shape from the React and Vue variants — this article focuses on the differences.
Sister articles:
- Laravel + React Starter Kit: Docker-verified production fork
- Laravel + Vue Starter Kit: Docker-verified production fork
Target
| Field | Value |
|---|---|
| Name | Laravel + Livewire Starter Kit |
| Official URL | https://github.com/laravel/livewire-starter-kit |
| Stack | Laravel 13 + Livewire v4 + Flux UI + Alpine + Fortify |
| Upstream license | MIT |
| Improvement license | MIT |
Verification date
2026-04-19
Environment
All steps ran inside Docker Desktop (CodeLift spec §5-6).
| Item | Value |
|---|---|
| Base image | php:8.5-cli-bookworm + Node 22 |
| PHP | 8.5.5 |
| Laravel Framework | 13.x |
| Composer | 2.9.7 |
| Node / npm | 22.22.2 / 10.9.7 |
| Frontend | Livewire v4 + Flux + Alpine |
| Test DB | SQLite |
| Upstream commit | laravel/livewire-starter-kit@62c60c8 |
Baseline
docker compose run --rm app on upstream main: 33 passed (77 assertions), 52s. Fewer tests than React/Vue (40/136); this variant exercises form flows through Livewire's component test harness rather than through Inertia HTTP tests, so the distribution of assertions differs.
What's different from the React and Vue variants
Laravel backend is shared, but the Livewire variant diverges on:
| Item | React / Vue | Livewire |
|---|---|---|
@laravel/vite-plugin-wayfinder |
Yes — Vite build shells out to artisan | No |
| Inertia | Yes — serializes initial props into inline <script> |
No |
Default middleware in bootstrap/app.php |
3 Inertia-related middlewares appended | Empty (callback body is just //) |
| Settings routes | PATCH/DELETE + Controller | Route::livewire(...) + internal AJAX actions |
So of the 8 findings from the React/Vue articles, 7 apply in Livewire, 1 (J) needs a different fix shape.
Improvements
A. README Setup section (weakened form)
Difference from React/Vue: the "composer install before npm run build or get an opaque Wayfinder autoload error" gotcha does not apply here — Livewire's vite.config.js has no @laravel/vite-plugin-wayfinder. The README still lacks a Setup section though, so we add one for contributor friendliness.
B. .env.example ships dev defaults with no production hints
Same as React/Vue. Inline production-override comments added.
C. config/app.php hardcodes the timezone
Same as React/Vue. Changed to env('APP_TIMEZONE', 'UTC').
D. No security response headers in the middleware stack (worse starting state than React/Vue)
Livewire-specific: bootstrap/app.php's withMiddleware() callback is empty (//). React/Vue appended three Inertia-related middlewares; Livewire ships with zero web middlewares explicitly appended.
Fix: the new SetSecurityHeaders is the first thing appended to the web group in this fork. Same CSP policy as React/Vue (production-only, 'unsafe-inline' kept). Livewire doesn't serialize initial state into inline scripts the way Inertia does, so the CSP could theoretically drop 'unsafe-inline', but Flux components and Alpine usage patterns can still emit inline handlers — moving to a nonce-based CSP is left for a dedicated follow-up.
New test file: tests/Feature/SecurityHeadersTest.php (2 assertions).
E. No HTTPS scheme enforcement helper
Same as React/Vue. URL::forceScheme('https') added in AppServiceProvider::configureDefaults guarded by isProduction().
F. Password rules — already handled upstream
Same state as the other variants. No change.
G. Login throttle is per email+IP, no account lockout
Same fix: layered RateLimiter::for('login', ...) — email+IP per-minute plus email-only per-hour.
H. Two-factor auth is available but not policy-enforced
Same design gap as the other variants. No code change.
I. No separated logging channel for auth events
Same fix: new auth daily channel, AuthActivitySubscriber subscribes to Laravel auth events + Fortify 2FA events. 2 new assertions.
J. Settings endpoints — Livewire variant requires a different approach, deferred
Livewire-specific: routes/settings.php uses Route::livewire(...) to render component pages. Profile updates, password changes, and 2FA toggles all flow through Livewire's internal AJAX endpoint (/livewire/update), not through per-field HTTP verbs. A route-level throttle:... only covers the initial page load, not component actions.
The right approach is per-component rate limiting with RateLimiter::tooManyAttempts inside the action methods on each Livewire component. That's a substantively different commit shape from React/Vue and is deferred to a Livewire-specific follow-up.
Before / after
| Dimension | Official | Improved |
|---|---|---|
php artisan test |
33 passed / 77 assertions | 37 passed / 92 assertions |
| README Setup section | None | Added |
Production hints in .env.example |
None | Inline comments |
APP_TIMEZONE takes effect |
No | Yes |
| Baseline security headers | None (empty middleware stack) | 4 always-on + HSTS / CSP in production |
| HTTPS scheme forcing | None | Production-only URL::forceScheme('https') |
| Login rate limit | Email + IP | Email + IP and email-only |
| Auth event logging | Mixed in default log | Dedicated auth daily channel |
| Settings endpoint rate limit | — | Deferred (Livewire-specific) |
When this improvement fits
- You're building on
laravel/livewire-starter-kitand want production security + observability baked in from day one. - You want to see how the Livewire variant differs from React/Vue in what hardening is still needed after scaffolding.
- You're curious how strict a CSP Livewire can run with — this pass keeps the same policy as the Inertia variants, and the next Livewire-specific article will tighten it.
Three-starter comparison preview
A follow-up comparison article will rank React / Vue / Livewire by production readiness. Laravel backend hardening cost is React ≈ Vue > Livewire (only because Livewire's middleware stack starts from empty — less to audit). But frontend maintenance, component-level rate limiting, and team skills make a simple ranking misleading.
Reproducing and adopting
Improvement branch: codelift-dev/livewire-starter-kit#improvements.
git clone https://github.com/codelift-dev/livewire-starter-kit.git
cd livewire-starter-kit
git checkout improvements
docker compose -f codelift/docker-compose.yml build
docker compose -f codelift/docker-compose.yml run --rm app
Application-level diff only (excluding the CodeLift codelift/ directory):
git diff main improvements -- . ':!codelift'
Each finding is a standalone commit, cherry-pickable.
License
- Upstream: MIT (Laravel LLC and contributors)
- Improvement: MIT (CodeLift / JIT Inc.)
Findings reflect the state on the verification date; upstream may change.
Featured in comparisons
Related articles
- Laravel + React Starter Kit: Docker-verified fork We took the official laravel/react-starter-kit (Inertia + React 19 + shadcn/ui + Fortify), ran it inside Docker Desktop to observe its actual behavior, and published a production-hardened fork with the complete commit-by-commit diff on Git…
- Laravel + Vue Starter Kit: Docker-verified fork We took the official laravel/vue-starter-kit (Inertia + Vue 3 + shadcn-vue + Fortify), ran it inside Docker, and published a production-hardened fork with the complete diff on GitHub. The finding set matches the React Starter Kit's, by des…
- Laravel + Livewire Starter Kit: nonce-based CSP The SetSecurityHeaders middleware shipped in our Livewire Starter Kit Docker-verified fork kept 'unsafe-inline' in script-src and style-src. That was a deliberate placeholder to match the React/Vue forks; the Livewire architecture doesn't …