ai-infrastructure-hugg…
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming,…
React Hook Form patterns - useForm, Controller, useFieldArray, validation resolver, performance optimization
Claude Code
$ npx -y skills add agents-inc/skills --skill web-forms-react-hook-form --agent claude-code
Codex
$ npx skills add agents-inc/skills --skill web-forms-react-hook-form -a codex -y
Cursor
$ npx skills add agents-inc/skills --skill web-forms-react-hook-form -a cursor -y
Gemini CLI
$ npx skills add agents-inc/skills --skill web-forms-react-hook-form -a gemini-cli -y
GitHub Copilot
$ npx skills add agents-inc/skills --skill web-forms-react-hook-form -a github-copilot -y
OpenCode
$ npx skills add agents-inc/skills --skill web-forms-react-hook-form -a opencode -y
Windsurf
$ npx skills add agents-inc/skills --skill web-forms-react-hook-form -a windsurf -y
name: web-forms-react-hook-form description: React Hook Form patterns - useForm, Controller, useFieldArray, validation resolver, performance optimization
> **Quick Guide:** `register` binds native inputs and keeps them uncontrolled; `Controller` wraps > components that hold their own value; `useFieldArray` drives repeatable rows and is keyed on > `field.id`. Validation arrives either as `register` rules or as a schema through `resolver`. > Re-renders are the thing to watch: `useWatch` and `useFormState` subscribe to named fields, > whereas `watch()` and a wide `formState` destructure subscribe to the whole form.
**Detailed Resources:**
---
stays uncontrolled, and typing re-renders nothing. Follow [examples/core.md](examples/core.md).
usable ref, so `Controller` supplies `value` and `onChange` and confines the re-render to that field. Follow [examples/controlled-components.md](examples/controlled-components.md).
the field-level `rules` drop out. Follow [examples/validation.md](examples/validation.md).
---
<critical_requirements>
**Call `useForm<FormData>()` with a generic and with `defaultValues` for every field.** The generic types each field path and the submit payload; the defaults mount every input controlled from the first render.
**Key `useFieldArray` rows on `field.id`.** It is the identity RHF assigns the row and it survives add, remove and reorder, which an array index does not.
**Reach for `Controller` as soon as a component holds its own value.** `register` needs a ref that reaches a native input, and a component that does not forward one never joins the form.
**Set `mode` to `"onBlur"` or `"onTouched"`.** The default `"onSubmit"` withholds feedback until the first submit, and `"onChange"` validates on every keystroke.
**Pass schema validation through `resolver`, with the schema in its own module.** A schema outside the component is testable on its own and reusable across forms, and the form keeps only the wiring.
</critical_requirements>
---
**Auto-detection:** react-hook-form, useForm, register, handleSubmit, formState, Controller, useFieldArray, useWatch, useFormContext, useFormState, FormProvider, FormStateSubscribe, SubmitHandler, resolver, shouldUnregister, valueAsNumber
**Applies to:**
**Handled elsewhere:**
in; how the schema states its rules is settled by whatever owns it.
option and fetches nothing itself.
---
<philosophy>
Form state lives outside React state. Inputs register themselves with the form and report through a ref, so a keystroke updates the form's own store without re-rendering the component that owns the field. Everything that reads form state — an error message, a computed total, a submit button — opts in by subscribing to a named slice, and a component that subscribes to nothing never re-renders.
This is why the wide reads cost so much. `watch()` in a render body and a `formState` destructure that pulls six properties both subscribe to the entire form, undoing the isolation the library was built for.
</philosophy>
---
<patterns>
The generic, `mode` and `defaultValues` together settle type safety, validation timing and controlled-input warnings.
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<ContactFormData>({
mode: "onBlur",
defaultValues: { name: "", email: "", message: "" },
});Full code: [examples/core.md](examples/core.md)
---
`Controller` renders the field itself and hands it `value` and `onChange`. The test for which to reach for: a component whose `ref` forwards to a native input works with `register`, and anything else needs `Controller`.
<Controller
name="service"
control={control}
rules={{ required: "Service is required" }}
render={({ field, fieldState: { error } }) => (
<>
<Select {...field} options={serviceOptions} />
{error && <span role="alert">{error.message}</span>}
</>
)}
/>Full code: [examples/controlled-components.md](examples/controlled-com
The official skills marketplace for Agents Inc. 230+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming,…
LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking,…
Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client…
Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output,…
Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning,…
Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling,…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.