scajal / laravel-react-starter-kit
An opinionated, production-minded starter kit for building SaaS apps with Laravel, Inertia and React.
Package info
github.com/scajal/laravel-react-starter-kit
Type:project
pkg:composer/scajal/laravel-react-starter-kit
Requires
- php: ^8.4
- bezhansalleh/filament-language-switch: ^5.0
- codewithdennis/filament-lucide-icons: ^4.1
- filament/filament: ^5.10
- inertiajs/inertia-laravel: ^3.0
- inertiaui/modal: ^3.1
- laravel-lang/common: ^6.8
- laravel/framework: ^13.17
- laravel/tinker: ^3.0
- laravel/wayfinder: ^0.1.14
- laravel/workos: ^0.6.0
- nunomaduro/essentials: ^1.2
- relaticle/activity-log: ^1.2
- spatie/laravel-activitylog: ^5.1
- spatie/laravel-data: ^4.23
- spatie/laravel-query-builder: ^7.3
Requires (Dev)
- barryvdh/laravel-ide-helper: ^3.7
- fakerphp/faker: ^1.24
- larastan/larastan: ^3.9
- laravel/boost: ^2.10
- laravel/pail: ^1.2.5
- laravel/pao: ^1.0.6
- laravel/pint: ^1.27
- laravel/sail: ^1.53
- mockery/mockery: ^1.6
- nunomaduro/collision: ^8.9.3
- pestphp/pest: ^5.3
- pestphp/pest-plugin-arch: ^5.0
- pestphp/pest-plugin-laravel: ^5.0
- pestphp/pest-plugin-phpstan: ^5.2
- pestphp/pest-plugin-type-coverage: ^5.0
- rector/rector: ^2.7
- spatie/laravel-typescript-transformer: ^3.3
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
π Laravel React Starter Kit
An opinionated, production-minded starter kit for building modern SaaS apps with Laravel, Inertia and React.
Authentication, teams, an admin panel, audit logs, i18n and a strict quality toolchain, all wired up so you can start on the features that matter.
π Table of contents
- β¨ Features
- π§± Tech stack
- ποΈ How it works
- β‘ Getting started
- π οΈ Available scripts
- π§ͺ Testing & quality
- π€ AI-assisted development
- π Project structure
- π§ Roadmap
- π€ Contributing
- π License
β¨ Features
| Feature | What you get | |
|---|---|---|
| π | Passwordless-ready auth | Sign-in handled by WorkOS AuthKit: SSO, social logins, magic links and MFA with no password storage in your app. Inactive users are signed out automatically. |
| π₯ | Teams & roles | Users belong to many teams through memberships with Owner, Administrator and Member roles, a current-team switcher and a permission enum ready for your rules. |
| π‘οΈ | Admin panel | A Filament 5 panel at /administration to manage users, teams and members, with an SPA feel, deferred tables and unsaved-changes alerts. |
| π | Audit trail | Every change to users, teams and memberships is logged with spatie/laravel-activitylog and shown as a timeline in the admin panel. |
| π | Internationalization | English π¬π§ and Spanish πͺπΈ out of the box, shared between Laravel and React. Only the active language's dictionary is downloaded. |
| π | Light / dark / system themes | The chosen appearance and locale are stored on the user's account and synced through cookies, so there's no flash of the wrong theme and preferences follow users across devices. |
| β‘ | SSR & React Compiler | Server-side rendering through @inertiajs/vite and automatic memoization with the React Compiler. |
| 𧬠| End-to-end types | Every prop is a laravel-data object, and TypeScript Transformer generates its exact TypeScript type, enums included. A test fails CI when the generated types drift. |
| π§ | Type-safe routing | Wayfinder generates TypeScript functions for your Laravel routes and controllers, so you never hardcode URLs again. |
| πͺ | Modals as routes | Inertia Modal opens any route in a modal or slideover, with deep-linkable URLs. |
| π¨ | shadcn/ui ready | Tailwind CSS 4, Base UI, Lucide icons and a pre-configured components.json. Run pnpm dlx shadcn add button and go. |
| π§° | Sensible defaults | Essentials turns on strict models, immutable dates, auto eager loading, stray-request prevention and no destructive commands in production. |
| π | ULID primary keys | Non-sequential, sortable IDs on every model. |
| β | Strict quality gates | Pest 5, PHPStan at max level, Rector, Pint, Vite+ lint/format and TypeScript checks, all running in GitHub Actions. |
π§± Tech stack
Backend
- π PHP 8.4+ & Laravel 13
- π Inertia.js 3 (server adapter)
- π‘οΈ Filament 5 with Lucide icons & a language switcher
- π Laravel WorkOS
- π spatie/laravel-activitylog + relaticle/activity-log timelines
- π spatie/laravel-query-builder
- 𧬠spatie/laravel-data + laravel-typescript-transformer
- π Laravel Lang
Frontend
- βοΈ React 19 + React Compiler
- π¦ TypeScript 7
- π¨ Tailwind CSS 4, Base UI & shadcn/ui
- β‘ Vite+ for building, linting and formatting
- π§ Wayfinder for typed routes
- π laravel-react-i18n
Tooling
- π§ͺ Pest 5 with arch, type-coverage and PHPStan plugins
- π¬ Larastan (max level) & Rector
- π Laravel Pint
- π€ Laravel Boost MCP server and agent skills
- π Laravel Pail and IDE Helper
ποΈ How it works
π Authentication flow
sequenceDiagram
actor U as User
participant App as Laravel app
participant W as WorkOS AuthKit
U->>App: GET / (protected)
App-->>U: Redirect to /login
App->>W: Redirect to hosted AuthKit
U->>W: Sign in (SSO, social, magic linkβ¦)
W-->>App: GET /authenticate?code=β¦
App->>App: Find user by WorkOS ID or email,<br/>create or update them
alt User is inactive
App-->>U: Sign out
else User is active
App-->>U: Redirect to intended page or home
end
Loading
Every authenticated route also runs WorkOS session validation, so a session revoked in WorkOS ends in your app too.
π₯ Identity model
erDiagram
USER ||--o{ MEMBERSHIP : has
TEAM ||--o{ MEMBERSHIP : has
USER ||--o{ PREFERENCE : stores
USER }o--o| TEAM : "current team"
USER {
ulid id
string name
string email
string external_id "WorkOS ID"
bool is_active
}
TEAM {
ulid id
string name
string slug "auto-generated, unique"
bool is_active
}
MEMBERSHIP {
ulid id
enum role "owner | admin | member"
}
PREFERENCE {
enum key "appearance | locale"
string value
}
Loading
π§© Modular architecture
Code is grouped by domain module under app/Modules instead of Laravel's default flat layout, so each area of the product keeps its models, HTTP layer, routes and admin resources together:
Authentication: WorkOS login, callback and logout.Core/Identity: users, teams, memberships, roles, permissions and preferences.Core/Audit: the activity log model and summaries.Administration: the Filament panel and its resources.Support: shared traits (HasActivation,AsOptions,DefinesKeyType) and the Inertia middleware.
Factories and tests mirror the same structure, so finding the test for any class is predictable.
π Shared Inertia props
Every page receives user, current_team, locale, appearance and an authorization object (admin access plus the current team's permissions). They are declared once, as the properties of SharedData, and HandleInertiaRequests shares one prop per property.
𧬠Typed props
Pages receive laravel-data objects, and php artisan typescript:transform generates their TypeScript types into resources/js/types/generated, one module per PHP namespace:
- Each page gets a
*Propsdata class under its module'sHttp/Pages, mirroring its file inresources/js/pages. - A shape only one page uses lives next to that page's props; it moves to the module's
Http/Dataonce a second page needs it. - Keys are snake_case on the wire, like the rest of Laravel.
β‘ Getting started
π Prerequisites
- PHP 8.4+ with the SQLite extension
- Composer 2
- Node.js 22+ and pnpm
- The Laravel installer (optional, but recommended)
- A free WorkOS account
1οΈβ£ Create your project
With the Laravel installer:
laravel new my-app --using=scajal/laravel-react-starter-kit --pnpm
cd my-app
This creates .env, generates the app key, creates the SQLite database, runs the migrations, and installs and builds the frontend with pnpm.
Other ways to create a project
With Composer:
composer create-project scajal/laravel-react-starter-kit my-app
cd my-app
pnpm install
pnpm run build
From the GitHub template: click Use this template, or clone the repository, then install everything with one command:
git clone https://github.com/scajal/laravel-react-starter-kit.git my-app
cd my-app
composer setup
2οΈβ£ After installing: configure WorkOS
The app signs users in through WorkOS, so it needs your WorkOS keys before anyone can log in.
- In the WorkOS dashboard, open Authentication β AuthKit and enable it.
- Under Redirects, set:
- Redirect URI:
http://localhost:8000/authenticate - Sign-in endpoint:
http://localhost:8000/login - Sign-out redirect:
http://localhost:8000
- Redirect URI:
- Copy your Client ID and API key into
.env:
WORKOS_CLIENT_ID=client_... WORKOS_API_KEY=sk_test_... WORKOS_REDIRECT_URL="${APP_URL}/authenticate"
3οΈβ£ Start developing
composer dev
This starts the web server, the queue worker, the log tail (Pail) and Vite in one terminal. Open http://localhost:8000, sign in through AuthKit and you're in! π
Tip
The admin panel lives at http://localhost:8000/administration. Out of the box, access is granted to any signed-in user in the local environment only. Update User::canAccessPanel() with your own rule before deploying.
ποΈ Using another database
SQLite is the default for zero-config local development. To switch to MySQL or PostgreSQL, update the DB_* variables in .env and run php artisan migrate.
π οΈ Available scripts
| Command | Description |
|---|---|
composer setup |
π¦ Install dependencies and bootstrap the app from scratch |
composer dev |
π₯ Run server, queue, logs and Vite together |
composer test |
π§ͺ Lint checks + the full Pest suite in parallel |
composer test:coverage |
π Run tests with a 100% code coverage gate |
composer test:types |
π Run tests with a 100% type coverage gate |
composer lint |
π§Ή Apply Rector and Pint fixes, then run PHPStan |
composer lint:check |
π Same checks without writing changes |
composer ci:check |
π¦ Everything CI runs: JS lint/format, TS types and tests |
pnpm run dev |
β‘ Vite dev server only |
pnpm run build |
ποΈ Production build |
pnpm run build:ssr |
π₯οΈ Production build with the SSR bundle |
pnpm run check / check:fix |
π Lint and format the frontend with Vite+ |
pnpm run types:check |
π¦ Type-check TypeScript |
php artisan typescript:transform |
𧬠Regenerate the TypeScript types of the data objects and enums |
π§ͺ Testing & quality
The kit treats quality as a feature:
- β Pest 5 feature and unit tests for every module
- π¬ PHPStan at max level via Larastan across
app,config,databaseandroutes - β»οΈ Rector for automated refactors and modern PHP syntax
- π Pint for consistent PHP style
- π§Ή Vite+ linting with type-aware rules (warnings fail the build) and formatting with sorted imports and Tailwind classes
- π¦ GitHub Actions runs the whole pipeline on every push and pull request
- π€ Dependabot keeps dependencies fresh
composer test
π€ AI-assisted development
This repository is built to work great with AI coding agents:
- π§ Laravel Boost MCP server (
.mcp.json) gives agents access to your schema, logs, routes and version-specific docs. - π
AGENTS.mdcarries the project's conventions for any agent. - π§© Agent skills for Claude Code, Cursor and Codex cover Inertia React, Filament, Wayfinder, Tailwind, Pest, activity logging and more.
Open the project in your favourite agent and it already knows how the codebase is meant to be written.
π Project structure
app/Modules/
βββ Administration/ # Filament panel, resources, relation managers
βββ Authentication/ # WorkOS login, callback & logout
βββ Core/
β βββ Audit/ # Activity log model & summaries
β βββ Identity/ # Users, teams, memberships, roles, preferences
βββ Support/ # Shared concerns & Inertia middleware
database/
βββ factories/Modules/ # Factories mirroring app/Modules
βββ migrations/
lang/ # en & es translations (PHP + JSON)
resources/
βββ css/ # App and admin panel themes
βββ js/
β βββ pages/ # Inertia React pages
β βββ lib/ # i18n & utilities
β βββ types/ # Shared prop typings
βββ views/ # Root Blade template
tests/
βββ Feature/Modules/ # Feature tests mirroring app/Modules
βββ Unit/Modules/ # Unit tests mirroring app/Modules
π§ Roadmap
Note
This kit is under active development. The foundations (auth, teams, admin panel, audit log, i18n, theming and tooling) are in place, while a few user-facing pieces are still on the way.
- π Home page: replace the placeholder
welcomepage with a real dashboard. - π Flash toasts: show server flash messages with shadcn's toast component.
- π₯ Team onboarding: send users who belong to no team to a team-creation page after signing in.
- π Team permissions: the
Permissionenum ships with a singleWildcardcase that only owners hold, ready for you to declare the actions your roles grant.
π€ Contributing
Contributions, issues and ideas are welcome! π‘
- Fork the repository
- Create a branch:
git checkout -b feature/amazing-thing - Make sure everything passes:
composer ci:check - Open a pull request π
If this kit saved you some time, consider giving it a β on GitHub. It really helps!
π License
Released under the MIT License.
Made with β€οΈ by Santiago Cajal