Search by

scajal / laravel-react-starter-kit

scajal

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

Statistics

Installs: 7

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

This package is auto-updated.

Last update: 2026-10-22 18:24:11 UTC


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.

Tests License: MIT Use this template

PHP Laravel Inertia React TypeScript Tailwind CSS Filament Pest PHPStan

πŸ“– Table of contents

✨ 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

Frontend

Tooling

πŸ—οΈ 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 *Props data class under its module's Http/Pages, mirroring its file in resources/js/pages.
  • A shape only one page uses lives next to that page's props; it moves to the module's Http/Data once 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.

  1. In the WorkOS dashboard, open Authentication β†’ AuthKit and enable it.
  2. Under Redirects, set:
    • Redirect URI: http://localhost:8000/authenticate
    • Sign-in endpoint: http://localhost:8000/login
    • Sign-out redirect: http://localhost:8000
  3. 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, database and routes
  • ♻️ 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.md carries 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 welcome page 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 Permission enum ships with a single Wildcard case that only owners hold, ready for you to declare the actions your roles grant.

🀝 Contributing

Contributions, issues and ideas are welcome! πŸ’‘

  1. Fork the repository
  2. Create a branch: git checkout -b feature/amazing-thing
  3. Make sure everything passes: composer ci:check
  4. 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