Shadcn Form
The shadcn/ui Form connects React Hook Form and Zod to accessible, Tailwind-styled fields. It handles labels, descriptions, and validation messages with the right ARIA wiring, so you write less boilerplate and ship accessible forms. Reach for it whenever a form needs client-side validation and inline error messages.
Key features
- Wraps React Hook Form with accessible field wiring.
- Schema validation with Zod through the resolver.
- Automatic labels, descriptions, and error messages with correct ARIA.
- Works with Input, Select, checkbox, and other fields.
- Swappable validators: Zod, Yup, Valibot, and more.
Installation
npx shadcn@latest add formThis adds the Form parts and installs react-hook-form, zod, and the resolver.
Usage
"use client"
import { z } from "zod"
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import {
Form,
FormField,
FormItem,
FormLabel,
FormControl,
FormDescription,
FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
const schema = z.object({
username: z.string().min(2, "At least 2 characters."),
})
export function ProfileForm() {
const form = useForm({
resolver: zodResolver(schema),
defaultValues: { username: "" },
})
function onSubmit(values: z.infer<typeof schema>) {
console.log(values)
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="shadcn" {...field} />
</FormControl>
<FormDescription>This is your public display name.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
)
}Anatomy
| Part | Purpose |
|---|---|
Form | Provider that shares the React Hook Form context. |
FormField | Connects a field to the form by name. |
FormItem | Groups a field's label, control, and message. |
FormLabel | Accessible label wired to the control. |
FormControl | Wraps the input and forwards ARIA attributes. |
FormDescription | Helper text for the field. |
FormMessage | Renders the field's validation error. |
Validation
Validation is schema-driven. Define a Zod schema, pass it through zodResolver, and FormMessage shows each error automatically with aria-invalid and aria-describedby set for you. Errors appear on submit and re-validate as the user corrects them.
Built on React Hook Form
The Form utilities wrap React Hook Form and are independent of the UI primitive layer. The fields you place inside (Input, Select, checkbox) follow their component APIs.
Accessibility
- Every field gets a programmatically associated label, description, and error, so screen readers announce state changes.
- Keep error messages specific and actionable ("Enter a valid email"), not generic ("Invalid input").
- Preserve labels during submission; disable the submit Button and show a spinner rather than replacing the form.
When to use the Form
Use the Form component whenever a form needs validation, error messages, or more than a couple of fields: sign-in, sign-up, checkout, settings, and contact. For a single uncontrolled field with no validation, a bare Input is enough. For multi-step flows, drive several useForm steps and validate each before advancing.
Related blocks
ShadcnStore's form blocks ship the field layouts as plain, framework-agnostic markup so they drop into any stack. Wire them to this Form component when you want React Hook Form validation:
- Login forms: sign-in layouts.
- Signup forms: account creation.
- Contact: contact and support forms.
- Checkout forms: billing and shipping.
Related components
A Form composes Input and Select fields, submits with a Button, and often lives inside a Card or a Dialog.
FAQ
What is the shadcn form used for?
The Form component wires React Hook Form and Zod to shadcn fields, giving accessible labels, descriptions, and validation messages with minimal boilerplate.
Does shadcn form use React Hook Form and Zod?
Yes. It is a thin wrapper around React Hook Form, with Zod as the recommended schema validator through the resolver.
How does validation work in shadcn form?
Define a Zod schema, pass it to useForm via zodResolver, and FormMessage renders each field's error automatically with the correct ARIA wiring.
Can I use a validator other than Zod?
Yes. React Hook Form supports resolvers for Yup, Valibot, and others; swap the resolver and keep the same field structure.