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.

Pascal BaljetBuilt by Pascal Baljet Creator of Inertia Table
ProjectKickoffForm.php
Rendered live from the PHP class by @inertiaui/form-vue. Every input works, go ahead.

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.

TextInputComboboxDatePickerRichTextRepeaterFileSliderOtpInputToggle+ 21 more
The form class API
PHPapp/Forms/OnboardingForm.php
class 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
VUEOnboarding.vue
<script setup>
import { Form } from '@inertiaui/form-vue'

defineProps(['form'])
</script>

<template>
  <Form :form="form" />
</template>
import { Form } from '@inertiaui/form-react'

export default function Onboarding({ form }) {
  return <Form form={form} />
}

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.

Validation and Precognition
PHPapp/Http/Controllers/WorkspaceController.php
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 fields
PHPapp/Forms/Fields/StarRating.php
class 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,
        ]);
    }
}
<script setup>
import { FieldWrapper, useFormField } from '@inertiaui/form-vue'

const props = defineProps(['name', 'label', 'maxStars'])

const { value, setValue, error, inputId } = useFormField(props)
</script>

<template>
  <FieldWrapper :field="props" :error="error" :input-id="inputId">
    <button
      v-for="star in props.maxStars"
      :key="star"
      type="button"
      @click="setValue(star)"
      v-text="star <= (value ?? 0) ? '★' : '☆'"
    />
  </FieldWrapper>
</template>
class ReviewForm extends Form
{
    public function fields(): array
    {
        return [
            TextInput::make('headline')->required(),

            StarRating::make('rating')
                ->maxStars(5)
                ->required(),

            Submit::make('Publish review'),
        ];
    }
}

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
VUEArticleControls.vue
<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.

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

Choices and records

Dates, values, and media

Editors and structure

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 Forms

Need every project covered? An unlimited license is available at checkout.