Remote OpenClaw
Menu
SkillsMCPPluginsFree guideDigestSubmit MCPSkillPluginMCPMCP, plugin, or skillAdvertise
Remote OpenClaw
SkillsMCPPluginsFree guideDigestSubmit MCPSkillPluginMCPMCP, plugin, or skillAdvertise

Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →
Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →
Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →
Skills/jezweb/claude-skills/react-hook-form-zod
react-hook-form-zod logo

react-hook-form-zod

jezweb/claude-skills
1K installs856 stars
Run it on Hostinger →up to 70% off + an extra 10% with code ZACAARON10Free API →

Installation

npx skills add https://github.com/jezweb/claude-skills --skill react-hook-form-zod

Summary

|

SKILL.md

React Hook Form + Zod Validation

Status: Production Ready ✅ Last Verified: 2026-01-20 Latest Versions: react-hook-form@7.71.1, zod@4.3.5, @hookform/resolvers@5.2.2

---

Quick Start

npm install react-hook-form@7.70.0 zod@4.3.5 @hookform/resolvers@5.2.2

Basic Form Pattern:

const schema = z.object({
  email: z.string().email(),
  password: z.string().min(8),
})

type FormData = z.infer<typeof schema>

const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
  resolver: zodResolver(schema),
  defaultValues: { email: '', password: '' }, // REQUIRED to prevent uncontrolled warnings
})

<form onSubmit={handleSubmit(onSubmit)}>
  <input {...register('email')} />
  {errors.email && <span role="alert">{errors.email.message}</span>}
</form>

Server Validation (CRITICAL - never skip):

// SAME schema on server
const data = schema.parse(await req.json())

---

Key Patterns

useForm Options (validation modes):

  • mode: 'onSubmit' (default) - Best performance
  • mode: 'onBlur' - Good balance
  • mode: 'onChange' - Live feedback, more re-renders
  • shouldUnregister: true - Remove field data when unmounted (use for multi-step forms)

Zod Refinements (cross-field validation):

z.object({ password: z.string(), confirm: z.string() })
  .refine((data) => data.password === data.confirm, {
    message: "Passwords don't match",
    path: ['confirm'], // CRITICAL: Error appears on this field
  })

Zod Transforms:

z.string().transform((val) => val.toLowerCase()) // Data manipulation
z.string().transform(parseInt).refine((v) => v > 0) // Chain with refine

Zod v4.3.0+ Features:

// Exact optional (can omit field, but NOT undefined)
z.string().exactOptional()

// Exclusive union (exactly one must match)
z.xor([z.string(), z.number()])

// Import from JSON Schema
z.fromJSONSchema({ type: "object", properties: { name: { type: "string" } } })

zodResolver connects Zod to React Hook Form, preserving type safety

---

Registration

register (for standard HTML inputs):

<input {...register('email')} /> // Uncontrolled, best performance

Controller (for third-party components):

<Controller
  name="category"
  control={control}
  render={({ field }) => <CustomSelect {...field} />} // MUST spread {...field}
/>

When to use Controller: React Select, date pickers, custom components without ref. Otherwise use register.

---

Error Handling

Display errors:

{errors.email && <span role="alert">{errors.email.message}</span>}
{errors.address?.street?.message} // Nested errors (use optional chaining)

Server errors:

const onSubmit = async (data) => {
  const res = await fetch('/api/submit', { method: 'POST', body: JSON.stringify(data) })
  if (!res.ok) {
    const { errors: serverErrors } = await res.json()
    Object.entries(serverErrors).forEach(([field, msg]) => setError(field, { message: msg }))
  }
}

---

Advanced Patterns

useFieldArray (dynamic lists):

const { fields, append, remove } = useFieldArray({ control, name: 'contacts' })

{fields.map((field, index) => (
  <div key={field.id}> {/* CRITICAL: Use field.id, NOT index */}
    <input {...register(`contacts.${index}.name` as const)} />
    {errors.contacts?.[index]?.name && <span>{errors.contacts[index].name.message}</span>}
    <button onClick={() => remove(index)}>Remove</button>
  </div>
))}
<button onClick={() => append({ name: '', email: '' })}>Add</button>

Async Validation (debounce):

const debouncedValidation = useDebouncedCallback(() => trigger('username'), 500)

Multi-Step Forms:

const step1 = z.object({ name: z.string(), email: z.string().email() })
const step2 = z.object({ address: z.string() })
const fullSchema = step1.merge(step2)

const nextStep = async () => {
  const isValid = await trigger(['name', 'email']) // Validate specific fields
  if (isValid) setStep(2)
}

Conditional Validation:

z.discriminatedUnion('accountType', [
  z.object({ accountType: z.literal('personal'), name: z.string() }),
  z.object({ accountType: z.literal('business'), companyName: z.string() }),
])

Conditional Fields with shouldUnregister:

const form = useForm({
  resolver: zodResolver(schema),
  shouldUnregister: false, // Keep values when fields unmount (default)
})

// Or use conditional schema validation:
z.object({
  showAddress: z.boolean(),
  address: z.string(),
}).refine((data) => {
  if (data.showAddress) {
    return data.address.length > 0;
  }
  return true;
}, {
  message: "Address is required",
  path: ["address"],
})

---

shadcn/ui Integration

Note: shadcn/ui deprecated the Form component. Use the Field component for new implementations (check latest docs).

Common Import Mistake: IDEs/AI may auto-import Form from "react-hook-form" instead of from shadcn. Always import:

// ✅ Correct:
import { useForm } from "react-hook-form";
import { Form, FormField, FormItem } from "@/components/ui/form"; // shadcn

// ❌ Wrong (auto-import mistake):
import { useForm, Form } from "react-hook-form";

Legacy Form component:

<FormField control={form.control} name="username" render={({ field }) => (
  <FormItem>
    <FormControl><Input {...field} /></FormControl>
    <FormMessage />
  </FormItem>
)} />

---

Performance

  • Use register (uncontrolled) over Controller (controlled) for standard inputs
  • Use watch('email') not watch() (isolates re-renders to specific fields)
  • shouldUnregister: true for multi-step forms (clears data on unmount)

Large Forms (300+ Fields)

Warning: Forms with 300+ fields using a resolver (Zod/Yup) AND reading formState properties can freeze for 10-15 seconds during registration. (Issue #13129)

Performance Characteristics:

  • Clean (no resolver, no formState read): Almost immediate
  • With resolver only: Almost immediate
  • With formState read only: Almost immediate
  • With BOTH resolver + formState read: ~9.5 seconds for 300 fields

Workarounds:

  1. Avoid destructuring formState - Read properties inline only when needed:
// ❌ Slow with 300+ fields:
const { isDirty, isValid } = form.formState;

// ✅ Fast:
const handleSubmit = () => {
  if (!form.formState.isValid) return; // Read inline only when needed
};
  1. Use mode: "onSubmit" - Don't validate on every change:
const form = useForm({
  resolver: zodResolver(largeSchema),
  mode: "onSubmit", // Validate only on submit, not onChange
});
  1. Split into sub-forms - Multiple smaller forms with separate schemas:
// Instead of one 300-field form, use 5-6 forms with 50-60 fields each
const form1 = useForm({ resolver: zodResolver(schema1) }); // Fields 1-50
const form2 = useForm({ resolver: zodResolver(schema2) }); // Fields 51-100
  1. Lazy render fields - Use tabs/accordion to mount only visible fields:
// Only mount fields for active tab, reduces initial registration time
{activeTab === 'personal' && <PersonalInfoFields />}
{activeTab === 'address' && <AddressFields />}

---

Critical Rules

✅ Always set defaultValues (prevents uncontrolled→controlled warnings)

✅ Validate on BOTH client and server (client can be bypassed - security!)

✅ Use field.id as key in useFieldArray (not index)

✅ Spread {...field} in Controller render

✅ Use z.infer<typeof schema> for type inference

❌ Never skip server validation (security vulnerability)

❌ Never mutate values directly (use setValue())

❌ Never mix controlled + uncontrolled patterns

❌ Never use index as key in useFieldArray

---

Known Issues (20 Prevented)

  1. Zod v4 Type Inference - #13109: Use z.infer<typeof schema> explicitly. Resolved in v7.66.x+. Note: @hookform/resolvers has TypeScript compatibility issues with Zod v4 (#813). Workaround: Use import { z } from 'zod/v3' or wait for resolver update.
  1. Uncontrolled→Controlled Warning - Always set defaultValues for all fields
  1. Nested Object Errors - Use optional chaining: errors.address?.street?.message
  1. Array Field Re-renders - Use key={field.id} in useFieldArray (not index)
  1. Async Validation Race Conditions - Debounce validation, cancel pending requests
  1. Server Error Mapping - Use setError() to map server errors to fields
  1. Default Values Not Applied - Set defaultValues in useForm options (not useState)
  1. Controller Field Not Updating - Always spread {...field} in render function
  1. useFieldArray Key Warnings - Use field.id as key (not index)
  1. Schema Refinement Error Paths - Specify path in refinement: refine(..., { path: ['fieldName'] })
  1. Transform vs Preprocess - Use transform for output, preprocess for input
  1. Multiple Resolver Conflicts - Use single resolver (zodResolver), combine schemas if needed
  1. Zod v4 Optional Fields Bug - #13102: Setting optional fields (.optional()) to empty string "" incorrectly triggers validation errors. Workarounds: Use .nullish(), .or(z.literal("")), or z.preprocess((val) => val === "" ? undefined : val, z.email().optional())
  1. useFieldArray Primitive Arrays Not Supported - #12570: Design limitation. useFieldArray only works with arrays of objects, not primitives like string[]. Workaround: Wrap primitives in objects: [{ value: "string" }] instead of ["string"]
  1. useFieldArray SSR ID Mismatch - #12782: Hydration mismatch warnings with SSR (Remix, Next.js). Field IDs generated on server don't match client. Workaround: Use client-only rendering for field arrays or wait for V8 (uses deterministic key)
  1. Next.js 16 reset() Validation Bug - #13110: Calling form.reset() after Server Actions submission causes validation errors on next submit. Fixed in v7.65.0+. Before fix: Use setValue() instead of reset()
  1. Validation Race Condition - #13156: During resolver validation, intermediate render where isValidating=false but errors not populated yet. Don't derive validity from errors alone. Use: !errors.field && !isValidating
  1. ZodError Thrown in Beta Versions - #12816: Zod v4 beta versions throw ZodError directly instead of capturing in formState.errors. Fixed in stable Zod v4.1.x+. Avoid beta versions
  1. Large Form Performance - #13129: 300+ fields with resolver + formState read freezes for 10-15 seconds. See Performance section for 4 workarounds
  1. shadcn Form Import Confusion - IDEs/AI may auto-import Form from "react-hook-form" instead of shadcn. Always import Form components from @/components/ui/form

---

Upcoming Changes in V8 (Beta)

React Hook Form v8 (currently in beta as of v8.0.0-beta.1, released 2026-01-11) introduces breaking changes. RFC Discussion #7433

Breaking Changes:

  1. useFieldArray: id → key:
// V7:
const { fields } = useFieldArray({ control, name: "items" });
fields.map(field => <div key={field.id}>...</div>)

// V8:
const { fields } = useFieldArray({ control, name: "items" });
fields.map(field => <div key={field.key}>...</div>)
// keyName prop removed
  1. Watch component: names → name:
// V7:
<Watch names={["email", "password"]} />

// V8:
<Watch name={["email", "password"]} />
  1. watch() callback API removed:
// V7:
watch((data, { name, type }) => {
  console.log(data, name, type);
});

// V8: Use useWatch or manual subscription
const data = useWatch({ control });
useEffect(() => {
  console.log(data);
}, [data]);
  1. setValue() no longer updates useFieldArray:
// V7:
setValue("items", newArray); // Updates field array

// V8: Must use replace() API
const { replace } = useFieldArray({ control, name: "items" });
replace(newArray);

V8 Benefits:

  • Fixes SSR hydration mismatch (deterministic key instead of random id)
  • Improved performance
  • Better TypeScript inference

Migration Timeline: V8 is in beta. Stable release date TBD. Monitor releases for stable version.

---

Bundled Resources

Templates: basic-form.tsx, advanced-form.tsx, shadcn-form.tsx, server-validation.ts, async-validation.tsx, dynamic-fields.tsx, multi-step-form.tsx, package.json

References: zod-schemas-guide.md, rhf-api-reference.md, error-handling.md, performance-optimization.md, shadcn-integration.md, top-errors.md

Docs: https://react-hook-form.com/ | https://zod.dev/ | https://ui.shadcn.com/docs/components/form

---

License: MIT | Last Verified: 2026-01-20 | Skill Version: 2.1.0 | Changes: Added 8 new known issues (Zod v4 optional fields bug, useFieldArray primitives limitation, SSR hydration mismatch, performance guidance for large forms, Next.js 16 reset() bug, validation race condition, ZodError thrown in beta, shadcn import confusion), added Zod v4.3.0 features (.exactOptional(), .xor(), z.fromJSONSchema()), added conditional field patterns with shouldUnregister, added V8 beta breaking changes section, expanded Zod v4 resolver compatibility notes, updated to react-hook-form@7.71.1

Score

0–100
55/ 100

Grade

C

Popularity15/30

1,241 installs — growing adoption.

Completeness19/30

Documented: full SKILL.md body, one-line install. Missing: description, category/license metadata.

Trust15/25

Community skill with a public GitHub source repository you can review.

Freshness6/15

No update timestamp is tracked for this skill in our catalog.

Scored automatically from popularity, completeness, trust, and freshness — computed only from data in our catalog, never fabricated.

Proud of your score? Add this badge to your README.

Paste a snippet into your GitHub README. The badge updates automatically and links back to this page.

React Hook Form Zod skill score badge previewScore badge

Markdown

[![React Hook Form Zod skill](https://www.remoteopenclaw.com/skills/jezweb/claude-skills/react-hook-form-zod/badges/score.svg)](https://www.remoteopenclaw.com/skills/jezweb/claude-skills/react-hook-form-zod)

HTML

<a href="https://www.remoteopenclaw.com/skills/jezweb/claude-skills/react-hook-form-zod"><img src="https://www.remoteopenclaw.com/skills/jezweb/claude-skills/react-hook-form-zod/badges/score.svg" alt="React Hook Form Zod skill"/></a>

React Hook Form Zod FAQ

How do I install the React Hook Form Zod skill?

Run “npx skills add https://github.com/jezweb/claude-skills --skill react-hook-form-zod” in your terminal. The skill is added to your agent's skills directory and picked up automatically on the next run — no restart or extra configuration needed.

What does the React Hook Form Zod skill do?

| The full SKILL.md on this page shows the exact instructions the skill gives your agent.

Is the React Hook Form Zod skill free?

Yes. React Hook Form Zod is a free, open-source skill published from jezweb/claude-skills. As with any third-party skill, review the source repository before installing it into an agent with sensitive access.

Does React Hook Form Zod work with Claude Code and OpenClaw?

Yes. Skills use the portable SKILL.md format, so React Hook Form Zod works with Claude Code, OpenClaw, Codex, Hermes, and any other agent that reads SKILL.md skills.

Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →
Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →
Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger →
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger →
Turn any website into LLM-ready data with Firecrawl logoTurn any website into LLM-ready data with Firecrawl

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits plus 10% off through our link.

Try Firecrawl free →
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now →
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free →
View on GitHub

Recommended skills

Browse all →
find-skills logo

find-skills

vercel-labs/skills

2.7M installsInstall
frontend-design logo

frontend-design

anthropics/skills

720K installsInstall
grill-me logo

grill-me

mattpocock/skills

701K installsInstall
agent-browser logo

agent-browser

vercel-labs/agent-browser

596K installsInstall
grill-with-docs logo

grill-with-docs

mattpocock/skills

594K installsInstall
vercel-react-best-practices logo

vercel-react-best-practices

vercel-labs/agent-skills

591K installsInstall

Browse

Skills by category

Frontend250Git198Data154Testing120Design105Docs103Security96Automation87Backend76Devops37Productivity29Mcp23

Related guides

Hand-picked reading to help you choose, install, and use agent skills.

Guide10 Openclaw Skills Every Nextjs Developer NeedsGuideBest Openclaw Skills 2026GuideHow To Evaluate Openclaw Skill Before Installing

Remote OpenClaw

AI agent skills directory, marketplace, and workflow hub for OpenClaw, Hermes Agent, Claude Code, Codex, and MCP-powered operator stacks.

The Agent Stack: weekly agent tooling digest, free.

Explore

  • Home
  • Skills Directory
  • Claude Code Skills
  • Codex Skills
  • MCP Clients
  • Marketplace
  • Hermes Ecosystem
  • Free guide
  • Learn
  • OpenClaw for Creators
  • OpenClaw for Founders
  • Blog
  • The Agent Stack (Digest)

More

  • Submit a Tool
  • Advertise
  • Playbook
  • Free Tools
  • API
  • Shipping
  • Contact
  • Terms
  • Privacy

Know a company that should advertise here? Refer them and earn 10% — up to $300 per referral.

© 2026 Remote OpenClaw
Fazier badgeFeatured on Twelve ToolsFeatured on Wired BusinessRemote OpenClaw - Featured on AI Agents DirectoryListed on Turbo0Featured on Uneed