Build serious forms
without wiring
every field.
Define fields, validation, uploads, and multi-step flows in one Laravel form class. Render it in Vue 3 or React 19 with a single component.
One class. The whole form.
Define the form in PHP and render it with one component. When a screen needs something bespoke, drop the fields straight into your template. Same components, same validation, either way.
Define it in PHP
The class holds the fields, labels, defaults, validation, visibility, and the submit route. Nothing to keep in sync on the frontend.
The form class APIclass OnboardingForm extends Form
{
public function fields(): array
{
return [
TextInput::make('name')->required(),
TextInput::make('email')->email()->precognitive(),
Combobox::make('plan')->options(Plan::class),
File::make('logo')->image()->disk('s3'),
Submit::make('Create workspace'),
];
}
}Render it with one component
One component renders every field and wires Precognition validation, uploads, and submit state. The same class drives Vue 3 and React 19.
Basic usage<script setup>
import { Form } from '@inertiaui/form-vue'
defineProps(['form'])
</script>
<template>
<Form :form="form" />
</template>Validate on submit
Type-hint the form class with #[Validate] and Laravel enforces the same rules server-side. Model binding fills an edit form from any Eloquent record.
class WorkspaceController
{
public function store(#[Validate] OnboardingForm $form)
{
$workspace = Workspace::create($form->validated());
return to_route('workspaces.show', $workspace);
}
}Bring your own fields
Extend Field in PHP, build the matching component, and register it once. From then on it works in any form class like a built-in, validation and all.
Building custom fieldsclass StarRating extends Field
{
use HasLabel;
use HasValidationRules;
protected int $maxStars = 5;
public function maxStars(int $max): static
{
$this->maxStars = $max;
return $this;
}
public function getComponent(): string
{
return 'StarRating';
}
public function toArray(): array
{
return array_merge(parent::toArray(), [
'label' => $this->getLabel(),
'maxStars' => $this->maxStars,
]);
}
}Every input stands alone
Every input is also a plain Vue and React component. Bind it with v-model or controlled props and use it anywhere in your app, no form class behind it.
Standalone components<script setup>
import { ref } from 'vue'
import { Combobox, TextInput, Toggle } from '@inertiaui/form-vue/components'
const title = ref('Launch notes')
const published = ref(true)
const status = ref('draft')
</script>
<template>
<TextInput v-model="title" label="Title" />
<Toggle v-model="published" label="Published" />
<Combobox
v-model="status"
label="Status"
:options="[
{ value: 'draft', label: 'Draft' },
{ value: 'published', label: 'Published' },
]"
/>
</template>Real forms, rendered live.
Switch between Laravel form classes and themes. Every preview is rendered from the serialized PHP definition, so you are seeing the real form, not a mockup.
Form class
Theme
Each theme is just a few CSS variables. The package brings no fixed palette or font stack, so every form blends into your app's colors and typography.
Laravel-native, all the way down.
Most production form behavior lives on the server. What lives in the browser stays fully in your control.
- Model binding Bind an Eloquent model and the form hydrates from attributes, casts, JSON paths, relations, and existing uploads. Unsaved-changes warning included.
- Upload strategies Temporary uploads by default, chunked for large files, direct-to-storage for S3, or store-with-form. Spatie Media Library supported.
- Precognition Real-time validation on blur through Laravel Precognition. The same server rules, no duplication in JavaScript.
- Conditional visibility Show, hide, and clear fields or whole fieldsets based on other values. Hidden fields are excluded from validation on the server.
- Authorization Gate single fields or the whole form with closures that call your policies. Unauthorized fields never leave the server.
- Wizard Long forms become stepped flows with progress, per-step validation, and configurable navigation. Same fieldsets, no second system.
- Timezones Date and time fields convert between the user's timezone and yours, so stored values stay unambiguous.
- Built for Tailwind CSS 4 Requires Tailwind 4.3+ and nothing else: no @tailwindcss/forms plugin. Every color, radius, and focus ring is a semantic CSS variable, dark mode included.
- Translations Built-in UI copy ships in a frontend registry: override any string with setTranslations(). Your own labels go through Laravel's translator.
- Slots, children, and data hooks Replace generated fields through Vue slots or React children, append your own content, and attach data-* hooks for analytics or end-to-end tests.
- Composables and hooks The same useForm and useFormField that power the built-ins are exported for your own components.
- Laravel Boost skills Boost loads Inertia Forms conventions into the agent's context, so it spends the run shaping the workflow your app needs instead of chasing component edge cases.
Laravel Boost + Inertia Forms
Don’t spend tokens on form edge cases.
Inertia Forms gives agents the form contract up front: inputs, validation feedback, uploads, model binding, and submit flows. That leaves the run for the workflow, rules, and product details that make the form yours.
- The field behavior is already there
- Inputs, errors, uploads, validation feedback, and renderers follow Inertia Forms instead of a one-off prompt.
- The run stays on your app
- Agents work on the form your product needs instead of chasing component edge cases.
- Laravel Boost
- Claude Code
- Codex
- Cursor
- Gemini CLI
Every field, finished.
Production-ready field workflows for the edge cases you would otherwise handle yourself: masks, uploads, timezones, nested validation, records, tags, and reordering. Every entry below opens its documentation.
Text and input
- TextInput Eleven input types with masks, currency and number formatting, icons, addons, keyboard shortcuts, and copyable or viewable values.
- Textarea Multi-line text that auto-resizes between min and max heights, with character counts and length limits.
- Slug URL-safe slugs generated live from another field, with separator control and respect for manual overrides.
- Link URLs as a plain string or a structured object with label and target, validated against allowed schemes.
- KeyValue Associative maps and ordered lists with custom headers, row limits, and drag reordering.
- Hidden Hidden values that still bind, validate, and submit like every other field.
Choices and records
- Combobox Finite choices with native select fallback, local search, grouped options, multiple selection, and typed custom values.
- Combobox Tokens String token entry with suggestions, delimiters, per-token rules, duplicate handling, clear-all, and drag reordering.
- Combobox Records Record-backed selection for Eloquent models or endpoints, with server search, selected lookup, pagination, rich media, quick create, and ordered IDs.
- Radio Single choice as plain radios, cards, pills, buttons, or a segmented control, with descriptions and icons.
- CheckboxGroup Multiple choice in the same five variants, with columns, icons, and select-all controls.
- Checkbox A single checkbox storing booleans or custom true and false values.
- Toggle A switch with labels, icons, three sizes, custom colors, and a loading state.
Dates, values, and media
- DatePicker Single dates, ranges, and multi-date selection with time, timezones, presets, markers, and disabled dates.
- TimePicker 12 or 24-hour time entry with minute steps, min and max boundaries, and disabled slots.
- FileUpload Drag-and-drop uploads with image previews, dimension rules, chunked and direct-to-storage transfers, reordering, and Spatie Media Library support.
- Slider Numbers and dual-thumb ranges with steps, marks, units, vertical orientation, and lazy updates.
- ColorPicker HSL sliders, swatches, alpha, an eyedropper, and copy to clipboard, stored in the format you choose.
- OtpInput One-time codes with grouping, paste and Web OTP autofill, password mode, and auto-submit.
Editors and structure
- RichText A TipTap editor with toolbar presets, link policy, embedded image uploads, and word and character counts.
- Composer A chat-style input for messaging and AI interfaces: auto-resize, Enter to send, attachments, and quick actions.
- Repeater A dynamic array of sub-forms for line items and lists, with nested validation, row limits, collapsible rows, and reordering.
- Blocks A page builder inside the form: mixed content blocks, each type with its own schema, preview header, defaults, and limits.
- Fieldset Groups fields with legends, descriptions, and grid columns. Doubles as the step source for wizards.
- Wizard Turns fieldsets into a stepped flow with progress, per-step validation, and configurable navigation.
- Submit Submit buttons with variants, sizes, icons, loading states, and multiple named actions.
Display
Shared JavaScript core
The layer underneath is ours.
Inertia UI Vanilla is the lightweight, pure JavaScript foundation behind Inertia Forms, Modal, and Table. The Vue and React packages all use it for the interaction behavior they share.
First-party primitives. No wrappers.
Every shared interaction is written and maintained here. That is what keeps Vue and React behaving the same way: a fix in one place lands everywhere at once.
It also means less adapter code, fewer workarounds around someone else's assumptions, and direct control over behavior on the day it needs to change.
Pay once. No subscription.
One license per project, a year of updates and new features included. Renew to stay current.
€179
Launch price · €199 later
Own an Inertia Table license? Yours for €149.
- Vue 3 + React 19
- 12 months of updates
- Full source code
- No auto-renewal
Every license includes the full source of both the Vue and React packages. Another year of updates costs €159, less than a new license.
Every form on this page is the real package, rendered live. You have already tried it.
Get Inertia FormsNeed every project covered? An unlimited license is available at checkout.