Skip to content

TanStack Form

Build forms in React using TanStack Form and Zod.

This guide will cover building forms using the Field component, adding schema validation with Zod, handling errors, ensuring accessibility, and more.

Demo

We’ll build a form with a text input and textarea. When you submit, the form data is validated and any errors will be shown.

Browser validation disabled

For the purposes of this demo, browser validation is disabled to illustrate schema validation. In production, keep native validation enabled when appropriate.

Bug Report
Help us improve by reporting bugs you encounter.
0/100 characters

Include steps to reproduce, expected behavior, and what actually happened.

Approach

This form uses TanStack Form for state and Zod for validation. We'll build forms using the Field component, which gives you complete flexibility over the markup and styling.

  • Uses TanStack Form's useForm hook for form state management.
  • Uses form.Field with a render function for controlled inputs.
  • Uses the Field components for building accessible forms.
  • Uses client-side validation by passing your Zod schema into validators.

Anatomy

Here's a basic example of a form using TanStack Form with the Field component.

Form

Create a schema

Define your form shape with a Zod schema.

Note: TanStack Form works with Zod and other Standard Schema libraries via its validators API.

form.tsx

Setup

  • Create the form with useForm from TanStack Form and pass your schema to the onSubmit option.
  • Use e.preventDefault() and e.stopPropagation() before calling form.handleSubmit()
form.tsx

Build

build the form using the form.Field from TanStack Form and the Shark Field.

Done

That's it. You now have a fully accessible form with client-side validation.

When you submit the form, the onSubmit handler receives validated values. If the form is invalid, TanStack Form exposes errors on field.state.meta.errors for FieldError.

Validation

Client-side

TanStack Form validates your form data using the Zod schema. Define a schema and pass it to the validators option of the useForm hook.

example-form.tsx

Modes

Configure when validation runs via the validators option:

form.tsx

Displaying Errors

Display errors next to the field using FieldError. For styling and accessibility:

  • Add the invalid prop to the Field component.
  • Don't need to add the invalid prop to the form control such as Input, Checkbox, etc.
form.tsx

Different types of fields

Input

  • Bind field.state.value and field.handleChange to Input.
  • Add the invalid prop to the Field component and pass the error message to the FieldError component.
Profile Settings
Update your profile information below.

This is your public display name. Must be between 3 and 10 characters. Must only contain letters, numbers, and underscores.

Textarea

  • Bind field.state.value and field.handleChange to Textarea.
  • Add the invalid prop to the Field component and pass the error message to the FieldError component.
Personalization
Customize your experience by telling us more about yourself.

Tell us more about yourself. This will be used to help us personalize your experience.

NativeSelect

  • Bind field.state.value and field.handleChange to NativeSelect.
  • Add the invalid prop to the Field component and pass the error message to the FieldError component.
Language Preferences
Select your preferred spoken language.

For best results, select the language you speak.

Select

  • Wire value and onValueChange on Select. For overlays, call field.handleBlur() from onInteractOutside when your example needs blur sync.
  • Add the invalid prop to the Field component and pass the error message to the FieldError component.
Language Preferences
Select your preferred spoken language.

For best results, select the language you speak.

Checkbox

  • Wire field.state.value and field.handleChange to Checkbox.
  • Add the invalid prop to the Field component and pass the error message to the FieldError component.
  • For checkbox arrays, use mode="array" on the form.Field component and TanStack Form's array helpers.
  • Remember to add data-slot="checkbox-group" to the FieldGroup component for proper styling and spacing.
Notifications
Manage your notification preferences.
Responses

Get notified for requests that take time, like research or image generation.

Tasks

Get notified when tasks you've created have updates.

Radio group

  • Wire field.state.value and field.handleChange to RadioGroup.
  • Add the invalid prop to the Field component and pass the FieldError component.
Subscription Plan
See pricing and features for each plan.
Plan

You can upgrade or downgrade your plan at any time.

Switch

  • Use field.state.value and field.handleChange with Switch.
  • Add the invalid prop to the Field component and pass the FieldError component.
Security Settings
Manage your account security preferences.

Enable multi-factor authentication to secure your account.

NumberInput

  • Wire field.state.value and field.handleChange to NumberInput.
  • Add the invalid prop to the Field component and pass the FieldError component.
Salary expectations
Share your target gross annual salary in EUR.
EUR

Slider

  • Wire field.state.value and field.handleChange to Slider.
  • Add the invalid prop to the Field component and pass the FieldError component.
Listings filter
Set a price range so we only show results in your budget.

Drag each thumb to set the lower and upper bound.

Combobox

  • Wire field.state.value and field.handleChange to Combobox.
  • Add the invalid prop to the Field component and pass the FieldError component.
Role setup
Tell us which team you work with most so we can tailor workflows.

Type to filter the list, then pick one option.

Autocomplete

  • Wire field.state.value and field.handleChange to Autocomplete.
  • Add the invalid prop to the Field component and pass the FieldError component.
Tech stack
Select the technology you're most familiar with.

Type to filter the list, then pick one option.

Date Picker

  • Wire field.state.value and field.handleChange to DatePicker.
  • Add the invalid prop to the Field component and pass the FieldError component.
Scheduling
Pick a day that works for a first-round interview. We will confirm by email.

Input OTP

  • Use field.state.value (as string[]) and field.handleChange with InputOTP.
  • Add the invalid prop to the Field component and pass the FieldError component.
Account recovery
Enter one of your single-use backup codes if you cannot access your authenticator app.

Codes can only be used once.

Rating

  • Wire field.state.value and field.handleChange to Rating.
  • Add the invalid prop to the Field component and pass the FieldError component.
Quick feedback
Help us improve by sharing how likely you are to recommend Shark UI to a colleague.

1 = not likely, 5 = very likely.

File Upload

  • Wire onFileAccept to sync files into form state.
  • Add the invalid prop to the Field component and pass the FieldError component.
Application materials
Upload your résumé or CV.

Accepted formats: PDF and Word documents.

Complex Forms

Here is an example of a more complex form with multiple fields and validation.

You're almost there!
Choose your subscription plan and billing period.
Subscription plan

Choose your subscription plan.

Choose how often you want to be billed.

Add-ons

Select additional features you'd like to include.

Advanced analytics and reporting

Automated daily backups

24/7 premium customer support

Receive email updates about your subscription.

Resetting the Form

Use form.reset() to reset the form to its default values.

Array Fields

TanStack Form provides powerful array field management with mode="array". This allows you to dynamically add, remove, and update array items with full validation support.

Contact emails
Manage your contact email addresses.
Email addresses

Add up to 5 email addresses where we can contact you.

Array Field Structure

Use mode="array" on the parent field to enable array field management.

form.tsx

Nested Fields

Access individual array items using bracket notation: fieldName[index].propertyName.

form.tsx

Adding Items

Use field.pushValue(item) to add items to an array field. You can disable the button when the array reaches its maximum length.

form.tsx

Removing Items

Use field.removeValue(index) to remove items from an array field. You can conditionally show the remove button only when there's more than one item.

form.tsx

Removing items

Use removeValue(index) on the array field.

form.tsx

Array validation

Validate arrays with Zod’s z.array() and .min() / .max().

form.tsx