Shadcn Form
React form component with type-safe validation using React Hook Form and Zod. Built with TypeScript and Tailwind CSS for Next.js applications.
Form validation getting complex?
Join our Discord community for help from other developers.
Building forms in React used to suck. This shadcn/ui setup combines React Hook Form with Zod validation so you get type safety, error handling, and all that good stuff without the usual headaches in your React apps.
Form showcase
A clean, accessible form with real-time validation:
React Hook Form handles the state, Zod catches the errors, and the accessibility stuff happens automatically. Styled with Tailwind CSS so it matches your design system instead of looking like basic HTML forms.
npx shadcn@latest add form
Why this doesn't suck like other form libraries
You've probably tried building forms in React before and wanted to give up. This free shadcn form actually works in your Next.js applications:
- Type safety - Zod catches your mistakes before users see them in your TypeScript projects
- Fast - React Hook Form doesn't re-render everything on every keystroke
- Actually accessible - Screen readers work, keyboard nav works in your JavaScript forms
- Composable - Mix and match components however you need
- Real-time validation - Show errors as people type, not after they submit
- Server-side too - Validate on both ends without duplicate code
- Just React - Not tied to any specific framework, works everywhere
Essential form patterns you'll build
Profile form
Multi-field form with different input types:
Select dropdown
Dropdowns that actually validate:
Checkbox groups
Pick multiple options, validate the whole array:
Combobox search
Search and select with validation:
Date picker
Date picker that actually validates dates:
Features
This free open source form component includes everything you need:
- TypeScript-first - Full type safety with schema validation and event types
- React Hook Form powered - Performant forms with minimal re-renders
- Zod validation - Catch errors before they reach your users
- Tailwind CSS styled - Customize with utilities, not fighting component CSS
- Accessible by default - Screen readers, keyboard navigation, focus management
- Form state management - Dirty fields, touched state, submission handling
- Real-time feedback - Validate as users type or on blur
- Server validation - Sync client and server validation rules
How to actually use this
1. Write your schema
Tell Zod what you expect:
import { z } from "zod"
const formSchema = z.object({
username: z.string().min(2, {
message: "Username must be at least 2 characters.",
}),
email: z.string().email({
message: "Please enter a valid email address.",
}),
})
2. Hook it up
Connect React Hook Form:
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
username: "",
email: "",
},
})
3. Build the thing
Put it all together:
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</form>
</Form>
API Reference
Core Components
Component | Purpose | Key Props |
---|---|---|
Form | Root form provider | ...formProps from useForm |
FormField | Controlled field wrapper | control , name , render |
FormItem | Field container | Groups label, control, message |
FormLabel | Accessible label | Auto-connects to field |
FormControl | Input wrapper | Provides field connection |
FormMessage | Error display | Shows validation errors |
FormDescription | Helper text | Optional field guidance |
Validation Modes
Mode | Trigger | Use Case |
---|---|---|
onSubmit | Form submission | Best performance (default) |
onBlur | Field loses focus | Long forms |
onChange | Every keystroke | Real-time validation |
onTouched | After first interaction | Balanced UX |
Schema Validation
Type | Pattern | Example |
---|---|---|
String | z.string().min().email() | Email, username, text |
Number | z.number().min().int() | Age, quantity, price |
Array | z.array().min().max() | Multi-select, tags |
Object | z.object().refine() | Complex validation rules |
Production tips
Validate early, validate often. This free shadcn/ui form gives you multiple validation modes—use them wisely. Show errors after users finish typing, not on every keystroke. This TypeScript component handles the timing—you provide feedback that helps instead of annoys users in your Next.js applications.
Write schemas that match reality. Zod catches impossible data, but it can't catch business logic. Email addresses need @ symbols, but they also need to be real addresses users can access. This open source shadcn component validates format—you validate meaning.
Handle loading states properly. Show spinners, disable buttons, give feedback during submission. Users will click "Submit" repeatedly if nothing happens. Your JavaScript form should respond immediately, even if processing takes time in your React applications.
Group related fields logically. Long forms overwhelm users. Use visual grouping, clear sections, and maybe multiple steps. This Tailwind CSS component handles any layout—you provide organization that matches user mental models.
Make errors actionable. "Invalid input" tells users nothing. "Username must be at least 3 characters" tells them exactly how to fix it. Clear error messages reduce support tickets and improve conversion rates.
Integration with other components
Forms naturally work with Input, Select, and Textarea components for data collection in your React applications. Use Button components for consistent action styling across all your forms.
For complex forms, combine with Tabs components to organize multi-step processes or Dialog components for modal forms. DatePicker and Checkbox components integrate seamlessly with the form validation system. This open source pattern keeps your forms consistent and accessible.
When building settings panels, pair forms with Switch components for toggles or RadioGroup for single selections. Alert components work well for showing form-level errors or success messages. Your JavaScript application can compose these components while maintaining proper validation.
For data tables, use forms with DataTable components for bulk actions or filtering. The form provides validation—other shadcn components handle specific input types and interactions.
Questions you might have
Shadcn Dropdown Menu
React dropdown menu component for actions, navigation, and settings. Built with TypeScript and Tailwind CSS for Next.js applications using Radix UI.
Shadcn Hover Card
React hover card component for contextual popups and user profile previews. Built with TypeScript and Tailwind CSS for Next.js applications using Radix UI.