react-forms
npx skills add https://github.com/olino3/forge --skill react-forms
Agent 安装分布
Skill 文档
skill:react-forms – Type-Safe Forms with React Hook Form + Zod
Version: 1.0.0
Purpose
Build type-safe, validated forms using React Hook Form v7 and Zod v4. A single Zod schema provides client-side validation, server-side validation, and full TypeScript inference via z.infer. This skill covers form setup, field registration, custom validation, error display, multi-step forms, dynamic fields, and Server Action integration. Use when building any form in React/Next.js that needs validation, type safety, or complex field interactions.
File Structure
skills/react-forms/
âââ SKILL.md (this file)
âââ examples.md
Interface References
- Context: Loaded via ContextProvider Interface
- Memory: Accessed via MemoryStore Interface
- Shared Patterns: Shared Loading Patterns
- Schemas: Validated against context_metadata.schema.json and memory_entry.schema.json
Form Development Focus Areas
- Schema Definition: Zod v4 schemas with transforms, refinements, and custom error messages
- Hook Form Integration:
useFormwithzodResolver, register patterns, controlled vs. uncontrolled - Type Inference:
z.infer<typeof schema>for form data types â no manual type definitions - Error Handling: Field-level errors, form-level errors, server errors, async validation
- Complex Forms: Multi-step wizards, dynamic field arrays, conditional fields, dependent validation
- Server Integration: Zod schema reuse in Server Actions, API routes, and middleware
- Performance: Uncontrolled components by default, selective re-renders via
watch, form state isolation - Accessibility: Labels, error announcements, required indicators, focus management on errors
Common Errors Prevented
- Defining form types manually instead of using
z.infer<typeof schema> - Using
onChangemode whenonBluroronSubmitis sufficient (causes unnecessary re-renders) - Forgetting
zodResolverinuseFormconfig â validation silently skipped - Not handling async default values (use
reset()after fetch, notdefaultValues) - Using
registerwith controlled components (MUI, Radix) â useControllerinstead - Missing
nameprop mismatch between schema and register - Zod schema not matching form field names exactly (case-sensitive)
- Not calling
handleSubmiton the form’sonSubmitâ raw form data instead of validated - Forgetting to disable submit button during
isSubmittingstate - Using
watch()at form level instead ofuseWatchfor individual fields (performance)
MANDATORY WORKFLOW (MUST FOLLOW EXACTLY)
Step 1: Initial Analysis
YOU MUST:
- Identify the form requirements:
- Fields, types, and validation rules
- Submission target (Server Action, API route, client-side)
- UI library (native HTML, MUI, Radix, shadcn/ui)
- Determine form complexity:
- Simple (single page, flat fields)
- Multi-step wizard
- Dynamic field arrays
- Dependent/conditional fields
- Check existing form patterns in the project
- Ask clarifying questions if needed
Step 2: Load Memory
Follow Standard Memory Loading with
skill="react-forms"anddomain="engineering".
YOU MUST:
- Use
memoryStore.getSkillMemory("react-forms", "{project-name}")to load project patterns - Use
memoryStore.getByProject("{project-name}")for cross-skill context (design system, component lib) - Review existing form conventions, validation patterns, and error display styles
Step 3: Load Context
Follow Standard Context Loading for the
engineeringdomain. Stay within the file budget declared in frontmatter.
Step 4: Implement Forms
YOU MUST follow this pattern:
1. Define Zod Schema (single source of truth):
import { z } from "zod"
export const userSchema = z.object({
name: z.string().min(2, "Name must be at least 2 characters"),
email: z.string().email("Invalid email address"),
age: z.coerce.number().min(18, "Must be 18 or older"),
role: z.enum(["admin", "user", "moderator"]),
})
// Type is inferred â never define manually
export type UserFormData = z.infer<typeof userSchema>
2. Wire React Hook Form:
"use client"
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import { userSchema, type UserFormData } from "./schema"
export function UserForm() {
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<UserFormData>({
resolver: zodResolver(userSchema),
defaultValues: { name: "", email: "", role: "user" },
})
async function onSubmit(data: UserFormData) {
// data is fully typed and validated
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
{/* Fields with error display */}
</form>
)
}
3. Reuse Schema on Server:
"use server"
import { userSchema } from "./schema"
export async function createUser(formData: FormData) {
const result = userSchema.safeParse(Object.fromEntries(formData))
if (!result.success) {
return { errors: result.error.flatten().fieldErrors }
}
// result.data is typed as UserFormData
await db.users.create({ data: result.data })
}
Rules:
- Always use
zodResolverâ never skip client-side validation - Always validate on the server too â client validation is a UX convenience, not a security layer
- Use
z.coercefor form fields that come as strings but need other types - Prefer
onSubmitvalidation mode for most forms - Use
Controllerfor third-party controlled components - Use
useFieldArrayfor dynamic field lists
DO NOT define form types manually â always use z.infer
Step 5: Generate Output
- Save to
/claudedocs/react-forms_{project}_{YYYY-MM-DD}.md - Follow naming conventions in
../OUTPUT_CONVENTIONS.md - Include schema file, form component, and server validation code
Step 6: Update Memory
Follow Standard Memory Update for
skill="react-forms".
Store form patterns, validation conventions, UI component integration patterns, and error display styles.
Compliance Checklist
Before completing, verify:
- Step 1: Form requirements and complexity identified
- Step 2: Standard Memory Loading pattern followed
- Step 3: Standard Context Loading pattern followed
- Step 4: Schema-first approach with Zod + React Hook Form implemented
- Step 5: Output saved with standard naming convention
- Step 6: Standard Memory Update pattern followed
Further Reading
- React Hook Form: https://react-hook-form.com/
- Zod: https://zod.dev/
- @hookform/resolvers: https://github.com/react-hook-form/resolvers
- Zod v4: https://v4.zod.dev/
Version History
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2026-02-12 | Initial release with interface-based architecture |