✓
If you've been building forms in React the traditional way — hand-written validation, error state management, manual field sync — you're doing 3x the work. React Hook Form + Zod fixes this in one pattern: define a schema once, get full type safety on both sides of the wire, and let the form validate itself.
The setup is deceptively simple. Define a Zod schema for your data shape. Wire it to React Hook Form's `useForm` hook via the `zodResolver`. The form now knows what fields exist, what types they should be, and what rules apply. Submit validation happens automatically. Errors render based on the same schema. If you change the schema, your form changes everywhere.
Here's the pattern:
```typescript
import { z } from 'zod';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
const ContactSchema = z.object({
email: z.string().email('Invalid email'),
message: z.string().min(10, 'At least 10 chars'),
subscribe: z.boolean().default(false),
});
type Contact = z.infer;
export function ContactForm() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(ContactSchema),
});
return (
);
}
```
The money part: on the server side, you don't write new validation. You use the same schema. A Supabase Edge Function or a Next.js Route Handler just runs `ContactSchema.parse()` on the request body. If the client sent garbage, the server rejects it. If someone bypassed the client validation entirely, the schema still catches it. One source of truth.
The catch is that Zod adds runtime overhead. If your form has 50 fields, parsing all of them on every keystroke costs CPU cycles. The solution is simple: validate on blur, not onChange. React Hook Form supports `mode: 'onBlur'` to run validation only when the field loses focus. For most forms, this is the right trade-off.
The other thing people get wrong: they define the schema inside the component. Move it outside. Keep your schema in a shared types file, import it in the component, import it again on the server. That's your single source of truth — not code duplication, actual data truth.
React Hook Form + Zod is the 2025 standard for building forms in React. If you're still managing validation state by hand, you've already lost. The boilerplate savings alone justify it — but the type safety and server validation guarantee are why you should actually care.