What this prompt does
This prompt has the AI build a type-safe React form using React Hook Form and Zod, with a single schema shared between client and server. You provide the [form_type], the [fields], the [server_runtime], and the [async_check]. It returns a shared Zod schema with types inferred via z.infer, a React Hook Form component bound through the Zod resolver, field-level errors with accessible labels, debounced async validation, optimistic submit states, and a matching server handler that re-validates with the same schema.
The structure works because the recurring form bug is client and server validation drifting apart. By making one Zod schema the single source of truth and re-validating on the server with it, the prompt closes that gap and keeps types and rules in sync. [fields] defines what the form renders and validates, [async_check] drives the debounced API validation (such as an email-uniqueness check), and [server_runtime] determines the shape of the server handler that re-runs the schema.
When to use it
- You're building a form and want one schema for both client and server validation.
- You keep hitting bugs where client rules and server rules silently diverge.
- You need accessible field errors and ARIA wiring done correctly.
- You require async validation, like an availability check, debounced against the API.
- You want optimistic submit with loading, success, and error states mapped back to fields.
- You want server-side re-validation to close the obvious security gap.
Example output
You get three full code sections: a shared Zod schema module with types inferred via z.infer for both sides; a React Hook Form component bound to that schema through the Zod resolver, rendering the [fields] with field-level error messages and accessible labels/ARIA wiring; debounced async validation for [async_check] surfaced on the field; optimistic submit with loading, success, and error states plus server-error mapping back onto fields; and the matching [server_runtime] handler that re-validates with the same schema.
Pro tips
- Keep the shared schema as the single source of truth — defining
[fields]once in Zod and inferring types withz.inferis what stops client and server rules from drifting. - Never skip the server re-validation in deliverable 6; client-only validation is bypassable, so re-running the schema in
[server_runtime]is the security line. - Set
[async_check]to your real need, like email uniqueness, and confirm it's debounced so you don't hammer the API on every keystroke. - List
[fields]precisely, since the component, schema, and error wiring are all generated from this value. - Match
[server_runtime]to your stack so the handler fits; a Next.js Route Handler differs from an Express endpoint in signature and request parsing. - Ask a follow-up to map specific server errors (like a duplicate email) back to the right field, so users see the message in context rather than as a generic banner.