Overview: The Quest for End-to-End Type Safety For years, developers building with Laravel have faced a persistent friction point: the communication gap between the PHP backend and the JavaScript or TypeScript frontend. While PHP has evolved into a robust, type-heavy language, those types often vanish the moment data hits the network. You might define a precise `Product` model or a strict `Enum` in Laravel, but your frontend remains blissfully unaware, forced to rely on manual type definitions that inevitably drift out of sync with the server. Laravel Wayfinder solves this by acting as an automated bridge. It doesn't just generate static files; it performs deep analysis of your application to extract routes, Inertia.js props, validation rules, and broadcast events, turning them into fully-typed TypeScript helpers. This ensures that a change in your Laravel controller immediately triggers a type error in your Vue.js or React components if the data contract is broken. It brings the "all-in-one" type safety of Livewire to the world of modern SPAs and separated repositories. Prerequisites To get the most out of this tutorial, you should be comfortable with: * **Laravel 10+**: Basic knowledge of routing, controllers, and Form Requests. * **Modern Frontend Frameworks**: Familiarity with React or Vue.js, specifically using Vite as a build tool. * **TypeScript Basics**: Understanding how interfaces and types provide editor autocomplete and build-time safety. * **GitHub Actions**: Basic knowledge of CI/CD workflows if you plan to sync types across separate repositories. Key Libraries & Tools * **Surveyor**: A "mostly static" analysis tool that inspects your PHP classes, methods, and bindings to extract raw metadata about your app. * **Ranger**: A layer above Surveyor that consumes raw data and transforms it into rich, digestible Data Transfer Objects (DTOs). * **Wayfinder Vite Plugin**: The client-side companion that watches for backend changes and triggers the regeneration of TypeScript definitions in real-time. * **Laravel Echo**: When combined with Wayfinder, it provides type-safe event broadcasting payloads. Code Walkthrough: Implementing Type-Safe Contracts 1. The Vite Integration Everything starts with the Vite configuration. You must register the Wayfinder plugin to enable the watcher that tracks your PHP files. ```javascript import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; import wayfinder from 'wayfinder-vite-plugin'; export default defineConfig({ plugins: [ laravel(['resources/js/app.ts']), wayfinder({ // Patterns of files to watch for changes watch: ['app/Http/Controllers/**', 'app/Models/**'] }), ], }); ``` 2. Auto-Generating Shared Props In an Inertia.js application, shared props (like the current user or flash messages) are notoriously difficult to type. Wayfinder analyzes your `HandleInertiaRequests` middleware to sync these automatically. ```php // app/Http/Middleware/HandleInertiaRequests.php public function share(Request $request): array { return array_merge(parent::share($request), [ 'auth' => [ 'user' => $request->user(), ], 'is_admin' => (bool) $request->user()?->admin, ]); } ``` On the frontend, Wayfinder performs **declaration merging** so that the `usePage` hook knows exactly what is available: ```typescript import { usePage } from '@inertiajs/react'; const { props } = usePage(); // TypeScript knows 'is_admin' exists and is a boolean if (props.is_admin) { console.log("Access granted"); } ``` 3. Validation via Form Requests One of the most powerful features in the latest beta is the extraction of validation rules. When you type-hint a `FormRequest` in your controller, Wayfinder generates a matching TypeScript interface. ```php // app/Http/Requests/ProductUpdateRequest.php public function rules(): array { return [ 'name' => 'required|string', 'price' => 'required|numeric|min:0', 'description' => 'nullable|string', ]; } ``` Wayfinder converts these rules into a type you can pass to Inertia's `useForm` hook, preventing you from sending the wrong data types to the server. ```typescript import { useForm } from '@inertiajs/react'; import { ProductUpdateRequest } from '@/types/generated'; const form = useForm<ProductUpdateRequest>({ name: '', price: 0, description: null, }); ``` Syntax Notes: Specificity Matters Wayfinder relies on the clarity of your PHP code. The more specific your types are in Laravel, the better the TypeScript output. For example, if a controller method returns a collection, use PHP DocBlocks or native type hints to specify the model within that collection. Wayfinder effectively "reads" your intent. If you mark a property as `nullable` in a Form Request, it will correctly append `| null` to the generated TypeScript definition. Practical Example: Jumping the Fence What happens if your Laravel backend and Vue.js frontend live in separate repositories? This is the "Jump the Fence" scenario. You can use a GitHub Actions workflow to keep them in sync. When you commit a change to the Laravel API, the workflow runs Wayfinder, generates the new types, and automatically opens a Pull Request against the frontend repository. This workflow ensures that the frontend team is immediately notified when a route changes or a new field is added to an API response. It turns a manual communication task into a fail-safe automated process. Tips & Gotchas * **Cashing Issues**: During beta, the internal cache of Surveyor can occasionally become corrupted. If your types aren't reflecting your PHP changes, try clearing your app cache or restarting the Vite dev server. * **Performance in Large Apps**: Because Wayfinder performs static analysis across your entire codebase, very large applications might experience a slight delay (a few seconds) between saving a PHP file and the TypeScript server picking up the change. * **Tree Shaking**: Unlike older tools that exported every route into a global object, Wayfinder exports individual route helpers. This allows modern bundlers to "tree-shake" away any routes that aren't actually imported in your frontend code, keeping your production bundles lean. * **Eloquent Resources**: Full support for complex `JsonResource` transformations is still in active development. For the most reliable results, stick to `arrayable` and `jsonable` objects for now.
Surveyor
Products
Jan 2026 • 1 videos
High activity month for Surveyor. Laravel among the most active voices, with 1 videos across 1 sources.
Jan 2026
- Jan 10, 2026