React Principles — Form Scaffold
You scaffold a React Hook Form + Zod form following the Form Validation with Zod recipe.
Step 0 — Load the live recipe (required)
Do this before anything else. The cookbook is the single source of truth and changes over time — never scaffold from memory or from the fallback summary below while the live recipe is reachable.
- If the
reactprinciplesMCP server is available, call itsget_recipetool with slugform-validation. - Otherwise fetch: https://www.reactprinciples.dev/cookbook/form-validation/llms.txt
The fetched recipe contains the principle, rules, canonical pattern code, and implementation examples — treat its rules as requirements, not suggestions. If both sources are unreachable (offline), use the fallback summary at the bottom of this file and tell the user you are working from a potentially outdated summary.
When to invoke
- User asks to "create a form" for a specific resource
- User asks to "scaffold a validation form"
- User mentions React Hook Form, Zod, or
zodResolver
Inputs needed
Ask the user for:
- Form purpose — create, edit, or both
- Resource name — e.g.,
User,Product. Used for component naming - Fields — list of field names with their Zod types (e.g.,
name: string min 1,email: string email) - Mutation hook — which React Query mutation will the form call (e.g.,
useCreateUser,useUpdateUser) - Location —
src/features/<feature>/components/
What to read first
Read existing form components and schemas in the user's project:
src/features/examples/components/UserForm.tsx # create form
src/features/examples/components/UserEditForm.tsx # edit form with pre-populated values
src/shared/utils/validators.ts # shared Zod schemas
src/features/examples/hooks/useCreateUser.ts # mutation hook pattern
Check if there's already a shared schema in src/shared/utils/validators.ts for this resource. If yes, reuse it via .omit() / .pick() / .extend() rather than duplicating.
How to scaffold
Derive the schema and the form component from the pattern and implementation code in the recipe you fetched in Step 0, adapted to the user's resource and fields:
- Follow the recipe's schema strategy: base schema in
src/shared/utils/validators.ts, create/edit variants derived from it - Mirror the structure of the existing forms you read, renaming resource and fields
- Apply every rule listed in the fetched recipe
After generating
Tell the user:
- The file path created
- Whether they need to add the schema to
src/shared/utils/validators.ts - Whether the mutation hook (
useCreate<Resource>,useUpdate<Resource>) exists — if not, suggest usingreactprinciples-queryskill - Import path:
import { <Resource>Form } from "@/features/<feature>/components/<Resource>Form"
What you should NOT do
- Don't put validation logic in
onSubmit— Zod handles it - Don't hardcode error messages in JSX — they should come from
formState.errors.<field>.message - Don't duplicate schemas — share via
.omit(),.pick(),.extend(),.partial() - Don't use Formik, react-final-form, or other form libraries — React Principles uses React Hook Form
- Don't generate raw
<input>styles inline if a UI primitive exists — recommend using@/ui/Input,@/ui/NativeSelect, etc.
Fallback summary (only if Step 0 fails)
May be outdated — the live recipe always wins.
- The Zod schema is the single source of truth; error messages live in the schema, never in JSX
- Use
zodResolverfrom@hookform/resolvers/zod; wrap mutation calls inhandleSubmit - Derive create/edit variants from a shared base schema via
.omit()/.partial()/.pick() 'use client'at the top; button state fromformState.isSubmittingreset()after a successful create;useEffect+reset(data)to pre-populate edit forms
Reference
See Form Validation with Zod recipe and existing forms in src/features/examples/components/.