Building blocks
What formdef does, and what it leaves to TanStack Form.
You write four things: a schema, a config per form, a registry per app, and the widgets the registry names. formdef turns them into a component that renders the form, and TanStack Form runs it.
What formdef does
| Block | What it does |
|---|---|
| Type layer | Derives the allowed config from the schema's data type and the registry, and rejects every mismatch at compile time. |
| Registry | Binds widgets, form components and structure slots under names, and builds TanStack's form hook with them. |
| Render loop | Walks a config and renders one TanStack field per entry, at the path it builds while descending. |
| Layout | Orders and groups the entries of one level: sections, rows, placed form components, inline entries. |
| Widget helpers | The wiring every widget repeats: ids, aria attributes, whether an error is due, the error texts. |
What TanStack does
Everything that happens to values at runtime belongs to TanStack Form: the store, when validation runs, the error maps, touched and dirty state, array operations and the submission. formdef never re-implements any of it.
formdef hands TanStack exactly two things: the options for the form, and the options for each field. Every key formdef does not know of passes through untouched, so a TanStack option you set in a config reaches TanStack as you wrote it.
The path of a form
createFormreceives the config. The type layer checks it against the schema's data type and the registry's widgets.- The component it returns merges the config with the instance's
optionsand creates the form with TanStack'suseAppForm. - It renders a
<form>element and, inside it,Fields. Fieldswalks the config's levels. For each leaf it renders a TanStack field and hands the widget that field as itsfieldprop.- The widget renders its control and reports changes to TanStack through
handleChange.