Laravel Wayfinder: Bridging the Gap Between PHP Backends and TypeScript Frontends

Laravel////5 min read

Overview: The Quest for End-to-End Type Safety

For years, developers building with have faced a persistent friction point: the communication gap between the PHP backend and the or 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.

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, props, validation rules, and broadcast events, turning them into fully-typed helpers. This ensures that a change in your Laravel controller immediately triggers a type error in your or components if the data contract is broken. It brings the "all-in-one" type safety of 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 or , specifically using 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 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 configuration. You must register the Wayfinder plugin to enable the watcher that tracks your PHP files.

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 application, shared props (like the current user or flash messages) are notoriously difficult to type. Wayfinder analyzes your HandleInertiaRequests middleware to sync these automatically.

// 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:

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 interface.

// 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.

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 output. For example, if a controller method returns a collection, use 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 definition.

Practical Example: Jumping the Fence

What happens if your Laravel backend and frontend live in separate repositories? This is the "Jump the Fence" scenario. You can use a 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 can occasionally become corrupted. If your types aren't reflecting your PHP changes, try clearing your app cache or restarting the 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 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.
Topic DensityMention share of the most discussed topics · 28 mentions across 16 distinct topics
25%· languages
11%· products
11%· products
7%· products
7%· products
Other topics
39%
End of Article
Source video
Laravel Wayfinder: Bridging the Gap Between PHP Backends and TypeScript Frontends

Laravel Wayfinder: End-to-End Type Safety Between Laravel & TypeScript w/ Joe Tannenbaum

Watch

Laravel // 1:02:50

The official YouTube channel of Laravel, the clean stack for Artisans and agents. We will update you on what's new in the world of Laravel, from the framework to our products Cloud, Forge, and Nightwatch.

Who and what they mention most
5 min read0%
5 min read