Skip to content
Development
Skill

/web-forms-tanstack-form

TanStack Form patterns - useForm, form.Field, validators, arrays, linked fields, createFormHook, type safety

From plugin
skills
26200 skills

Claude Code

$ npx -y skills add agents-inc/skills --skill web-forms-tanstack-form --agent claude-code

SKILL.md

web-forms-tanstack-form.SKILL.md
name: web-forms-tanstack-form
description: TanStack Form patterns - useForm, form.Field, validators, arrays, linked fields, createFormHook, type safety

TanStack Form Patterns

> **Quick Guide:** `useForm` takes `defaultValues`, and every field name, value type and the submit > payload are inferred from that object. Fields render through `form.Field` with a `children` render > prop that supplies `field.state.value`, `field.handleChange` and `field.handleBlur`. Validation > lives in the `validators` prop — keyed by event (`onChange`, `onBlur`, `onSubmit`) with an `Async` > variant of each, on the field or on the form. `mode="array"` unlocks `pushValue`/`removeValue`, > `onChangeListenTo` re-runs a validator when another field changes, and `form.Subscribe` narrows > which state changes re-render what.

**Detailed Resources:**

  • [examples/core.md](examples/core.md) — a form end to end: fields, typing, submission, reset
  • [examples/validation.md](examples/validation.md) — sync, async and cross-field validators; schema objects in validators
  • [examples/arrays.md](examples/arrays.md) — dynamic field groups with `mode="array"`
  • [examples/composition.md](examples/composition.md) — `createFormHook`, `useAppForm`, listeners
  • [reference.md](reference.md) — validator events, field and form state tables, API methods, framework packages

---

Which path applies

  • **A single form** — `useForm` plus `form.Field` render props, nothing else to set up. Follow

[examples/core.md](examples/core.md).

  • **Forms across an app that should behave alike** — `createFormHook` registers shared field and

form components once, and `useAppForm` replaces `useForm` at each call site. Follow [examples/composition.md](examples/composition.md).

  • **A framework other than React** — the form core is shared and only the package and the field

binding differ; reference.md's Framework Packages table names both for each.

---

<critical_requirements>

Before writing TanStack Form code

**Give `useForm` a `defaultValues` entry for every field.** Field names, value types and the submit payload are all inferred from that object, so a field missing from it is a field the types do not know about.

**Render every field through `form.Field` and its `children` render prop.** The render prop receives the value and the handlers explicitly — this library has no field-registration helper and does no ref forwarding, so an input wired any other way never joins the form.

**Put validation in the `validators` prop, keyed by the event that should run it.** `onChange`, `onBlur` and `onSubmit` each have an `Async` counterpart, and the same prop exists on the field and on the form.

**Read `field.state.meta.errors` as an array.** It holds every current error for the field, so `.map()` over it or check `.length`; compared against a string it is always unequal.

**Call `e.preventDefault()` in the form's `onSubmit` before `form.handleSubmit()`.** The library does not intercept the native submit, so without it the browser navigates away mid-submission.

</critical_requirements>

---

**Auto-detection:** @tanstack/react-form, @tanstack/vue-form, @tanstack/solid-form, @tanstack/angular-form, @tanstack/lit-form, @tanstack/form-core, form.Field, form.Subscribe, createFormHook, createFormHookContexts, useAppForm, withForm, fieldContext, formContext, field.handleChange, field.handleBlur, field.state.meta, pushValue, removeValue, swapValues, onChangeListenTo, onBlurListenTo, setErrorMap, formDevtoolsPlugin

**Applies to:**

  • Form state, validation timing and submission
  • Cross-field rules, where one field's validity depends on another's value
  • Dynamic lists of field groups that add, remove and reorder
  • Sharing field and form components across an app through the factory
  • Forms in Vue, Solid, Angular or Lit as well as React

**Handled elsewhere:**

  • Authoring the validation schema — a validator accepts any Standard Schema object, and how that

schema states its rules is settled by whatever owns it.

  • Rendering and styling the inputs — this library owns no UI; the render prop hands over the value

and the handlers, and the markup is yours.

  • Where the initial values came from — `defaultValues` is a plain object, and the form fetches

nothing.

---

<philosophy>

The form is headless and its types run on inference. `defaultValues` is the schema of record: field names autocomplete from it, `field.state.value` is typed by it, and the `onSubmit` payload matches it — without a generic parameter, and without a second type declaration that could drift.

Validation is bound to events rather than to a mode. Each validator declares when it runs, at the level it belongs to, so a cheap format check can sit on `onChange` while the expensive uniqueness check waits for `onBlurAsync` on the same field.

State is read by subscription. `form.Subscribe` and `useStore` take a selector and re-render only when what the selector returns changes, so reading `form.state` directly in a component body opts out of the whole design.

</philosophy>

---

<patterns>

Core patterns

Pattern 1: useForm and form.Field

The render prop is the whole field API — value in, handlers out, nothing implicit.

const form = useForm({
  defaultValues: { name: "", email: "" },
  onSubmit: async ({ value }) => {
    await submitToApi(value);
  },
});

<form
  onSubmit={(e) => {
    e.preventDefault();
    form.handleSubmit();
  }}
>
  <form.Field
    name="email"
    children={(field) => (
      <input
        value={field.state.value}
        onBlur={field.handleBlur}
        onChange={(e) => field.handleChange(e.target.value)}
      />
    )}
  />
</form>;

`onBlur={field.handleBlur}` is what marks the field touched — omit it and `isTouched` stays false and any `onBlur` validator never runs.

Full code: [examples/core.md](examples/core.md)

---

Pattern 2: Field-level validators

A sync validator returns a message string, or `undefined` when the value p

Read more
@agents-inc
Ships withskills

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?

Stars on GitHub

Momentum

stars in total
26
Star history of agents-inc/skills on GitHub, a chart by star-history.com

Other skills on skills.

ai-infrastructure-litellm

ai-infrastructure-lite…

LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking,…

@agents-inc@agents-incInstall Skill
ai-infrastructure-modal

ai-infrastructure-moda…

Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client…

@agents-inc@agents-incInstall Skill
ai-infrastructure-ollama

ai-infrastructure-olla…

Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output,…

@agents-inc@agents-incInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about web-forms-tanstack-form.

Which coding agents can use web-forms-tanstack-form?
web-forms-tanstack-form installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.