A FIELD GUIDE TO LARAVEL · VOLUME II · THE ECOSYSTEM
ENTRY II.45 · TYPED ROUTES
Wayfinder
Laravel\Wayfinder · Package · first recorded 2 April 2025, v0.1.0 on Packagist; expanded type generation in public beta since December 2025
TypeScript generated from the Laravel app: the frontend imports a controller action and gets its URL, method and parameters typed. Change a route in PHP and the TypeScript errors say where. A next version, in beta, adds models and enums.
Specification
Kind Package plus a Vite plugin; a generator, nothing resident; pre-1.0
Interface Generated TypeScript: show(1) returns { url, method }; .url(), .form()
Client Any TypeScript frontend; Inertia's useForm() and Link take the result
Installed by composer require laravel/wayfinder · npm i -D @laravel/vite-plugin-wayfinder
Voice wayfinder:generate · --with-form · --skip-actions · --skip-routes
Scales by Regenerated on every Vite build and file change; the output is disposable
Range Cloud: yes, at build time; npm run build comes before optimize in the default build
Forge, VPS: yes, in the deploy script; route:clear first if routes were cached
Vapor: yes, in the vapor.yml build steps, before any route:cache
Neighbours
Inertia serves the pages; Wayfinder types the URLs they call, and its calls pass straight to Inertia's form helper and Link. The React, Vue and Svelte starter kits ship with it. Its distinction is that the import is the controller method itself, so a renamed action fails at build time, not at click time.
Field marks
resources/js/actions/ · routes/
resources/js/wayfinder/
wayfinder() in vite.config.js
@laravel/vite-plugin-wayfinder
Fig. II.45.1 · From PHP route to typed call
Parts
1 Controller, PostController@show with its route parameters. The PHP side is the source of truth; nothing is declared twice.
2 Router. Wayfinder reads the registered routes, so a stale route:cache left from the last release hides the new ones.
3 wayfinder:generate, run by the Vite plugin on build and on file change. Output under resources/js, regenerated in full each time.
4 Generated module. @/actions/App/Http/Controllers/PostController and @/routes/post: one typed function per action or route name.
5 Call site. show(1) gives { url, method }; show.url(1), show.form(1) and update.form.put(1) are the variants.
6 Inertia, optional. form.submit(update(1)) and <Link href={show(1)}> resolve the URL and method themselves.
Hidden joinery
A JavaScript reserved word used as a controller method gets a Method suffix, so delete becomes deleteMethod. Several routes on one action export a dictionary keyed by URI, or verb plus URI on a collision. A custom key such as {post:slug} is honoured, so you pass { slug }. Importing a whole controller defeats tree-shaking.
Every line checked on 2026-10-08 against docs, source, Packagist and The Monitor; see the ledger.
TITLE
Wayfinder · typed routes for TS
SOURCES
github.com/laravel/wayfinder · github.com/laravel/wayfinder/tree/next · packagist.org/packages/laravel/wayfinder · laravel.com/docs/13.x/starter-kits · github.com/laravel/breeze · laravel.com/cloud/docs/deploy-guides/laravel · laravel.com/blog/laravel-wayfinder-end-to-end-type-safety-for-php-and-typescript · laravel.com/blog/laravel-december-product-releases · Monitor 606, 607
STATUS
Verified · 2026-10-08
SHEET
II.45 of 48
REV
A · 2026-10-08
DRAWN
BS
FINISH
All faces, including the back