xelqun / forms
PHP-defined, schema-driven forms for Laravel, Inertia and Vue.
v0.1.1
2026-11-05 08:32 UTC
Requires
- php: ^8.4
- illuminate/contracts: ^13.0
- illuminate/database: ^13.0
- illuminate/filesystem: ^13.0
- illuminate/http: ^13.0
- illuminate/support: ^13.0
- illuminate/validation: ^13.0
- inertiajs/inertia-laravel: ^3.0
Requires (Dev)
- larastan/larastan: ^3.9
- laravel/pint: ^1.27
- orchestra/testbench: ^11.0
- pestphp/pest: ^5.3
- pestphp/pest-plugin-laravel: ^5.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Describe a form in PHP and generic Vue components render it. Normal forms need no Vue at all.
Pre-alpha: the API will change. Requires Laravel 13, Inertia 3, Vue 3.5 and Tailwind 4.
Example
class OrderForm extends Form { public function schema(): array { return [ TextInput::make('customer')->required(), Select::make('country_id')->relationship('country', 'name'), Repeater::make('items')->relationship()->schema([ TextInput::make('qty')->numeric(), TextInput::make('price')->numeric(), TextInput::make('subtotal')->computed('qty * price')->disabled(), ]), TextInput::make('total')->computed('sum(items.*.subtotal)')->disabled(), ]; } }
Features
- Write PHP, not Vue. Normal forms need no frontend code.
- Instant browser rules. Conditions and calculations run without a server call, and the server re-checks them on submit.
- Small server updates. Dependent fields update through small patches that keep focus and cursor position.
- Secure by default. Forms rebuild from an encrypted token, and every endpoint re-runs
authorize()and validation. - Repeaters and uploads included. Nested rows map to validation errors, and files upload as soon as they're picked.
Installation
composer require xelqun/forms && php artisan xelqun-forms:install
The installer adds the matching @xelqun/forms npm package and sets up resources/js/app.ts and resources/css/app.css.
Usage
class OrderController { // Show the form: GET /orders/{order}/edit public function edit(Order $order) { return Inertia::render('Orders/Edit', [ 'form' => OrderForm::make($order)->toSchema(), 'orderId' => $order->id, ]); } // Save the form: PUT /orders/{order} public function update(Request $request, Order $order) { OrderForm::make($order)->save($request); return back(); } }
<script setup lang="ts"> import { XqForm, type FormSchema } from '@xelqun/forms'; defineProps<{ form: FormSchema; orderId: number }>(); </script> <template> <XqForm :form="form" :action="`/orders/${orderId}`" method="put" /> </template>
Plugins
Other packages can add fields, with the same search, uploads, rows and saving as built-in ones. Install one with php artisan xelqun-forms:plugin acme/rating, or build one with the plugin guide.
Before going to production
- Add your rules to
authorize(). It allows everything by default. - Schedule
php artisan xelqun-forms:prune-uploads. Temporary uploads stay on disk until it runs.
License
MIT
