# Docs - [Introduction](/docs): Fast React forms where every field is a Jotai atom. - [Getting started](/docs/getting-started): This page takes you from installing Wit Form to a working form with validation and a submit handler. It takes about five minutes. - [Core concepts](/docs/core-concepts): Six ideas explain almost everything Wit Form does. Read this page once and the API pages will make sense quickly. - [Comparison](/docs/comparison): How Wit Form compares with React Hook Form, TanStack Form and Formik: where it fits, and where another library is the better choice. - **Guides** - [Validation](/docs/guides/validation): Wit Form validates single fields, field arrays and the whole form, with plain functions, async checks or a schema (Zod, Valibot, ArkType and others). This guide covers each one and when to use it. - [Type-safe forms](/docs/guides/type-safety): createFormHooks gives you the Wit Form hooks typed for your form values: TypeScript checks every field name, including fields inside field array rows, and types each value by its path. - [Field arrays](/docs/guides/field-arrays): A field array is a list of rows that all have the same fields: line items on an invoice, guests on a booking, rows in a spreadsheet. useFieldArray manages the list. useField still manages each input inside it. - [Watching values](/docs/guides/watching-values): Forms often need to show something based on what the user has entered: a live preview, a running total, a field that appears only for some answers. Wit Form has hooks that read values without re-rendering the whole form. - [Loading and saving data](/docs/guides/loading-and-saving): Most real forms edit something that already exists: a user profile, a settings page, an order. This guide covers starting values, loading data after a fetch, tracking unsaved changes, saving and resetting. - [Performance](/docs/guides/performance): Wit Form is fast by default: changing a field re-renders that field and the components watching it, nothing else. You don't need React.memo or careful prop drilling. This page explains the few things that can undo that, and the options for very large forms. - [Migrating from react-recoil-form](/docs/guides/migrating): Wit Form is the successor to react-recoil-form. It has the same API, with Jotai in place of Recoil, and it works on React 18 and newer. - **API Reference** - [FormProvider](/docs/api/form-provider): FormProvider holds the state of one form. Every Wit Form hook, including useForm, must be called by a component inside it. Each FormProvider is independent, so several forms can share a page without mixing values. - [useForm](/docs/api/use-form): useForm controls the form as a whole: what happens on submit, the initial values, form-level validation and schemas, the form state, and resetting. Call it once per form, in a component inside the FormProvider. - [useField](/docs/api/use-field): useField connects one input to one value in the form. It gives you the current value, a function to change it, the validation error and the touched state. The component that calls it re-renders only when this field changes. - [Field](/docs/api/field): is a component version of useField. It connects one input to the form without a separate hook call. Use it for simple inputs, or when you'd rather not write a component per input type. - [useFieldArray](/docs/api/use-field-array): useFieldArray manages a list of rows that share the same fields: line items, guests, table rows. It tracks which rows exist and in what order, and gives you functions to add, insert, move and remove them. The inputs inside each row are still regular useField fields. - [Watch hooks](/docs/api/watch-hooks): Watch hooks read form values and keep a component up to date as they change. Each one re-renders only the component that calls it, and only when the values it reads change. Call them in small components, close to where the value is shown. See the Watching Values guide. - [useFormState](/docs/api/use-form-state): useFormState reads the form state (isValid, isDirty, isSubmitting, errors and more) from any component inside the form. A component re-renders only when a property it reads changes. - [useFormContext](/docs/api/use-form-context): useFormContext lets any component inside the form read and change it from code, even if the component isn't a field. Use it for buttons like "Use my saved address", lookups that fill in other fields, or reading values in an event handler. - [useSetFormProps](/docs/api/use-set-form-props): useSetFormProps lets a component inside the form replace the form-level validate function that was passed to useForm. Use it when the rules depend on something only a child component knows about, like which tab or section is shown. - [createFormHooks](/docs/api/create-form-hooks): createFormHooks returns the Wit Form hooks typed for your form values, so TypeScript checks field names and infers value types from them. - [Types](/docs/api/types): Wit Form ships TypeScript types. These are the ones you're most likely to use in your own code: - **Examples** - [Overview](/docs/examples): Complete, working forms. Each example has a live preview and its full source. - Getting Started - [Quick Start](/docs/examples/getting-started/quick-start): Fill in the form and submit. Leave a required field empty to see its error after you blur it or submit. - [Field Component](/docs/examples/getting-started/field-component): The same form features without writing a hook per input. Submit with the email empty to see the built-in required check. - Validation - [Field Rules](/docs/examples/validation/field-rules): Errors show after you leave a field, or for every field when you submit. Validation itself runs on every change, so an error clears as soon as you fix it. - [Cross-field Rules](/docs/examples/validation/cross-field-rules): The new password can't match the current one, and the confirmation must match the new password. Change the new password after confirming it and the confirmation re-validates. - [Dynamic Rules](/docs/examples/validation/dynamic-rules): The amount starts above your balance, so submitting fails. Add funds and submit again: the same amount is now checked against the new balance. - [Async Rules](/docs/examples/validation/async-rules): Check a username against the server while the user types, and show errors that only the server can find after a submit. - [Schema Rules](/docs/examples/validation/schema-rules): Validate the whole form with one Zod schema. Errors appear on the matching fields, including fields inside field array rows, and rules across fields become form errors. - [Form-level Rules](/docs/examples/validation/form-level-rules): The initial values break several booking rules. Submit to see form-level errors next to field errors, then fix them. - Field Arrays - [Invoice](/docs/examples/field-arrays/invoice): Add, duplicate and remove line items. Row amounts and the total update as you type, and each one re-renders only when the values it watches change. - [Nested Arrays](/docs/examples/field-arrays/nested-arrays): A field array inside a field array. Each section has its own list of lessons and its own running duration. - Watching Values - [Conditional Fields](/docs/examples/watching-values/conditional-fields): Change the answers and watch fields appear and disappear. When a field unmounts its value is removed, so hidden fields never leak into the submitted values. - [Live Preview](/docs/examples/watching-values/live-preview): The preview and the character counter watch only the fields they show. The yellow badges count renders: the form itself never re-renders as you type. - Patterns - [Multi-step Wizard](/docs/examples/patterns/multi-step-wizard): Each step is validated before you can move on. Go back and forth: values from hidden steps are kept, and the review step reads them all. - [Edit a Record](/docs/examples/patterns/edit-a-record): Change something and the Save button turns on. Discard puts the loaded values back. Turn on “Fail the next save” to see a failed save keep your edits. - [Imperative Updates](/docs/examples/patterns/imperative-updates): Fill fields from code: load a saved address, look up a city from a ZIP code, copy one address into another, or clear one. - [Extra Info & Files](/docs/examples/patterns/extra-info-and-files): Each field can carry an extraInfo next to its value. Pick an assignee and upload an image, then compare the values and extra infos on the right. - Advanced - [Render Performance](/docs/examples/advanced/render-performance): Edit any cell and watch the yellow render counters: only that cell and its column total re-render, however many rows there are. - [Outside the Provider](/docs/examples/advanced/outside-the-provider): The order summary lives outside the form's FormProvider, in a different part of the page. It reads and updates the form through its formId.