Form

Type-safe form validation utilizing web fundamentals using Conform and Zod (or Valibot).

  • Seamless form submission experience out of the box

  • Clean, declarative API

  • Type-safety powered by Zod

  • Single validation source for client & server using Zod

  • Built-in accessibility and keyboard navigation

  • Field auto-focus on validation error

  • Optimized for React 19 / Next 15 and Server Components

  • Prevents automatic form reset after submission

  • Zod error messages animated with Motion

  • Progressive enhancement–first APIs

Model

Installation

Enter your license key

Unlock the shadcn registry to install components.

Usage

The usage consists of the following steps:

  1. Define Zod schema for form validation
  2. Use the useForm hook provided by Pure UI or Conform
  3. Use Form component
  4. Utilize *Field components or manually handle form fields
  5. Use Conform’s parseWithZod in the server action

useForm

The useForm hook is a React hook that integrates Zod schema validation with form handling using the Conform library.

It’s designed for use with RSC, specifically leveraging useActionState. It accepts a Zod schema, an optional submission result, and an action. The hook ensures validation happens on blur and revalidation occurs on input, preventing the default form reset behavior while keeping the last submission result in sync.

"use client"

import { useActionState } from "react"
import { useForm } from "@/hooks/use-form"

import { FORM_VALIDATION_ACTION } from "./actions"
import { ZodFormValidationSchema } from "./schema"

export default function ValidationDemo() {
  const [actionResult, action, pending] = useActionState(
    FORM_VALIDATION_ACTION,
    undefined,
  )

  const [form, fields] = useForm({
    actionResult,
    action,
    schema: ZodFormValidationSchema,
  })

  return ...
}

Essentially, it's a wrapper around the Conform useForm hook, which removes some boilerplate and provides a more convenient API and sensible defaults. You can use Conform hook instead if you prefer.

The hook returns a tuple containing form and fields metadata that you can use to enhance a HTML form by using Form and *Field components with the provided metadata.

Form

Uses Conform’s getFormProps and sets all props required to make a form element accessible. To function properly, pass the form metadata returned by useForm hook as the validate prop.

export default function ValidationDemo() {
  const [form, fields] = useForm(...)

  return (
    <Form validate={form}>
      ...
    </Form>
  )
}

Form Fields

To enhance the developer experience, additional form field components are provided that wrap inputs, adding styling, error messages, labels, and Conform’s meta binding.

To ensure proper functionality, pass the appropriate field from the fields metadata returned by the useForm hook as the validate prop.

...
import { ZodFormValidationSchema } from "./schema"

export default function ValidationDemo() {
  ...
  const [form, fields] = useForm({
    schema: ZodFormValidationSchema,
    ...
  })

  return (
    <Form validate={form}>
      <InputField validate={fields.email} />
    </Form>
  )
}

Checkbox Field

Enter your license key

Unlock the shadcn registry to install components.

PropTypeDefault
size
enum
"default"
radius
enum
invalid
boolean
reduceMotion
boolean
false
validate
FieldMetadata<string | boolean | undefined>
label
ReactNode | string

Input Field

Enter your license key

Unlock the shadcn registry to install components.

PropTypeDefault
type
enum
"text"
size
enum
"default"
radius
enum
invalid
boolean
reduceMotion
boolean
false
validate
FieldMetadata<string | boolean | undefined>
label
ReactNode | string

Textarea Field

Enter your license key

Unlock the shadcn registry to install components.

PropTypeDefault
size
enum
"default"
radius
enum
invalid
boolean
reduceMotion
boolean
false
minRows
number
2
maxRows
number
resize
enum
validate
FieldMetadata<string | boolean | undefined>
label
ReactNode | string

Radio Group Field

Enter your license key

Unlock the shadcn registry to install components.

Choose a model
PropTypeDefault
size
enum
"default"
invalid
boolean
reduceMotion
boolean
false
options*
RadioOption[]
validate
FieldMetadata<string | boolean | undefined>
label
ReactNode | string

Select Field

Loading...
PropTypeDefault
options*
OptionDataProps[]
groupedOptions*
GroupedOptionDataProps[]
size
enum
"default"
radius
enum
reduceMotion
boolean
false
indicator
ReactNode
animation
AnimationProps
animationPreset
enum
transition
Transition
transitionPreset
enumTransitionPreset
placeholder
ReactNode
icon
ReactNode
invalid
boolean
validate
FieldMetadata<string | boolean | undefined>
label
ReactNode | string

Switch Field

Loading...
PropTypeDefault
size
enum
"default"
invalid
boolean
elastic
boolean
reduceMotion
boolean
false
validate
FieldMetadata<string | boolean | undefined>
label
ReactNode | string

Slider Field

Loading...
PropTypeDefault
validate
FieldMetadata<string | boolean | undefined>
size
enum
"default"
label
ReactNode | string

Custom Field

You’re not limited to using only *Field components. If you need more control over component rendering, you can use any input component with validation:

Native Inputs

You can even use native HTML inputs:

Conform Wrappers

If you don’t need Label, FormField, or error messages, you can use form inputs wrapped with Conform directly.

CheckboxConform

PropTypeDefault
size
enum
"default"
radius
enum
invalid
boolean
reduceMotion
boolean
false
validate
FieldMetadata<string | boolean | undefined>

InputConform

PropTypeDefault
type
enum
"text"
size
enum
"default"
radius
enum
invalid
boolean
reduceMotion
boolean
false
validate
FieldMetadata<string | boolean | undefined>

RadioGroupConform

PropTypeDefault
size
enum
"default"
invalid
boolean
reduceMotion
boolean
false
options*
RadioOption[]
validate
FieldMetadata<string | boolean | undefined>

SelectConform

PropTypeDefault
options*
OptionDataProps[]
groupedOptions*
GroupedOptionDataProps[]
size
enum
"default"
radius
enum
reduceMotion
boolean
false
indicator
ReactNode
animation
AnimationProps
animationPreset
enum
transition
Transition
transitionPreset
enumTransitionPreset
placeholder
ReactNode
icon
ReactNode
invalid
boolean
validate
FieldMetadata<string | boolean | undefined>

SwitchConform

PropTypeDefault
size
enum
"default"
invalid
boolean
elastic
boolean
reduceMotion
boolean
false
validate
FieldMetadata<string | boolean | undefined>

TextareaConform

PropTypeDefault
size
enum
"default"
radius
enum
invalid
boolean
reduceMotion
boolean
false
minRows
number
2
maxRows
number
resize
enum
validate
FieldMetadata<string | boolean | undefined>

API Reference

Form

PropTypeDefault
validate*
FormMetadata<input<T>, string[]>
invalidAnimation
enum

FormFieldSet

PropTypeDefault
legend
ReactNode | string
messages
string[]
size
enum
"default"

FormField

PropTypeDefault
messages
string[]
size
enum
"default"

FormFieldMessages

PropTypeDefault
messages
string[]
size
enum
"default"