joshcirre/inertiakit
Composer 安装命令:
composer require joshcirre/inertiakit
包简介
File-based Inertia routing, simplified server controllers + typed models & props
README 文档
README
inertiaKIT
inertiaKIT is a zero-boilerplate approach to file-based routing and typed props in Laravel + InertiaJS created by Josh Cirre. It auto-generates:
- Routes (and optional Controllers) from
resources/js/pages/*.server.php - TypeScript interfaces for your Eloquent models
- TypeScript interfaces for your page props, with camelCased keys and model types
Installation
-
Require the package
composer require joshcirre/inertiakit
-
Install the package
php artisan inertiakit:install
-
(Optional but recommended) Install Laravel Wayfinder for zero-config route-action types:
composer require laravel/wayfinder
Configuration
Edit your config/inertiakit.php to tailor:
return [ // Explicit Eloquent models to type, or empty = auto-discover all under app/Models 'models' => [], // Where to write your generated TS model interfaces 'types_output' => 'resources/js/types/models.d.ts', // Generate real Controllers under app/Http/Controllers/Generated 'use_controllers'=> env('INERTIAKIT_USE_CONTROLLERS', true), // Where to dump your auto-generated routes file 'routes_file' => 'routes/inertiakit.php', // Glob patterns under resources/js/pages to ignore 'ignore' => [ 'auth/*', 'settings/*', 'welcome', 'dashboard', ], ];
Usage
Run the generation command manually once, or run the following as needed:
php artisan inertiakit:generate # Generate routes, controllers, and types php artisan inertiakit:model-types # Generate TypeScript types for models php artisan inertiakit:page-types # Generate TypeScript types for page props
Defining Page Data & Actions
Each page pairs a React/Vue/Svelte component with a PHP server file (.server.php). Use the fluent ServerPage API to define your page:
<?php use InertiaKit\ServerPage; use InertiaKit\Prop; use App\Models\Todo; use Illuminate\Http\Request; return ServerPage::make('Todos/Index') ->middleware('auth') ->loader(fn () => [ 'todos' => Todo::all(), 'completedCount' => Prop::defer(fn () => Todo::where('completed', true)->count()), 'tags' => Prop::merge(fn () => Todo::pluck('tag')->unique()->values()), ]) ->post('addTodo', function (Request $request) { Todo::create($request->validate([ 'title' => 'required|string', 'completed' => 'boolean', ])); }) ->put('updateTodo', function (Todo $todo, Request $request) { $todo->update($request->validate([ 'title' => 'string', 'completed' => 'boolean', ])); }) ->delete('deleteTodo', function (Todo $todo) { $todo->delete(); }) ->types([ 'todos' => 'App\\Models\\Todo[]', ]);
Inertia 2 Prop Types
InertiaKit integrates with Inertia 2's prop semantics through the Prop class. Wrap any prop value in a Prop factory to control how Inertia delivers it:
use InertiaKit\Prop; ->loader(fn () => [ // Standard prop — included on every visit 'todos' => Todo::all(), // Deferred — loaded asynchronously after initial page render 'stats' => Prop::defer(fn () => Stats::compute()), // Deferred with group — batched with other props in the same group 'permissions' => Prop::defer(fn () => Permission::all())->group('sidebar'), // Optional — only included when explicitly requested via partial reload 'roles' => Prop::optional(fn () => Role::all()), // Merge — appended to existing data on subsequent visits (great for pagination) 'tags' => Prop::merge(fn () => Tag::paginate()), // Deep merge — recursively merged into existing nested data 'config' => Prop::deepMerge(fn () => loadNestedConfig()), // Always — included on every request, even partial reloads 'notifications' => Prop::always(fn () => auth()->user()->unreadNotifications), ])
TypeScript types are automatically generated with the correct optionality:
deferandoptionalprops become optional properties (propName?: Type)merge,deepMerge, andalwaysprops remain required (propName: Type)
Explicit HTTP Method Actions
Define actions with explicit HTTP methods for full control over your route verbs:
return ServerPage::make('Todos/Index') ->post('addTodo', function (Request $request) { ... }) ->put('updateTodo', function (Todo $todo, Request $request) { ... }) ->patch('toggleTodo', function (Todo $todo, Request $request) { ... }) ->delete('deleteTodo', function (Todo $todo) { ... })
You can also use the generic ->action() method, which auto-detects the HTTP method based on parameter types:
- Model only →
DELETE - Model + Request →
PUT - Request only →
POST
Dynamic Route Parameters
Use [param] folder names to create dynamic route segments, SvelteKit-style:
resources/js/pages/
├── users/
│ ├── index.server.php → GET /users
│ └── [user]/
│ └── edit.server.php → GET /users/{user}/edit
The loader receives route-model bound parameters automatically:
<?php // resources/js/pages/users/[user]/edit.server.php use App\Models\User; use InertiaKit\ServerPage; use InertiaKit\Prop; return ServerPage::make('Users/Edit') ->middleware('auth') ->loader(fn (User $user): array => [ 'user' => $user, 'roles' => Prop::optional(fn () => $user->roles), ]) ->types([ 'user' => User::class, ]) ->put('updateProfile', function (User $user, Request $request) { $user->update($request->validate([ 'name' => 'required|string', 'email' => 'required|email', ])); });
The generated controller automatically includes route-model binding in the method signature, and Laravel resolves the User model from the {user} URL segment.
Note: Parameterized loaders cannot be executed at build time for type inference. Always add
->types()to pages with dynamic route parameters.
Client-Side Usage
On the client, InertiaKit injects typed actions and props that you can use:
import type { TodosIndexProps } from '@/types/page-props'; import { useForm, usePage } from '@inertiajs/react'; import { addTodo } from '@/actions/App/Http/Controllers/Generated/Pages/TodosIndexController'; export default function TodosIndex() { const { props } = usePage<TodosIndexProps>(); const form = useForm({ title: '', description: '' }); const submit = (e: React.FormEvent) => { e.preventDefault(); form.submit(addTodo(), { onSuccess: () => form.setData({ title: '', description: '' }), preserveScroll: true, }); }; return ( <div> <h1>My Todos</h1> {props.todos.map((todo) => ( <div key={todo.id}> <p>{todo.title}</p> </div> ))} <form onSubmit={submit}> <input value={form.data.title} onChange={(e) => form.setData('title', e.target.value)} /> <button type="submit" disabled={form.processing}>Add Todo</button> </form> </div> ); }
Automatic Re-generation with Vite
For seamless DX, you can hook up a file watcher in your vite.config.js. (This is done automatically when you run inertiakit:install)
npm install -D vite-plugin-run
And in your vite.config.js:
import laravel from 'laravel-vite-plugin'; import { run } from 'vite-plugin-run'; import { defineConfig } from 'vite'; export default defineConfig({ plugins: [ laravel({ input: ['resources/css/app.css', 'resources/js/app.tsx'], ssr: 'resources/js/ssr.tsx', refresh: true, }), run([ { name: 'inertiakit:types', run: ['php', 'artisan', 'inertiakit:model-types && php artisan inertiakit:page-types'], pattern: ['app/Models/**/*.php', 'resources/js/pages/**/*.server.php'], }, ]), ], });
Further Reading
joshcirre/inertiakit 适用场景与选型建议
joshcirre/inertiakit 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 10 次下载、GitHub Stars 达 5, 最近一次更新时间为 2025 年 04 月 25 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「package」 「php」 「Skeleton」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 joshcirre/inertiakit 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 joshcirre/inertiakit 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 joshcirre/inertiakit 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Simple ASCII output of array data
Slim starter / Slim skeleton package to boost your development with Slim framework
Base Skeleton for Laravel Application
An awesome skeleton for modern PHP development.
Alfabank REST API integration
统计信息
- 总下载量: 10
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 5
- 点击次数: 16
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-04-25