Skip to content
API reference

form

TS
const effectValidator: <S>(
self,
options?,
) => StandardSchemaV1<S["Encoded"], S["Type"]> & S = Schema.toStandardSchemaV1;

Effect’s maintained Standard Schema adapter, including nested issue paths.

Returns a “Standard Schema” object conforming to the Standard Schema v1 specification.

Details

This function creates a schema whose validate method attempts to decode and validate the provided input synchronously. If the underlying Schema includes any asynchronous components (e.g., asynchronous message resolutions or checks), then validation will necessarily return a Promise instead.

Example (Creating a standard schema from a regular schema)

TS
import { Schema } from "effect";
// Define custom hook functions for error formatting
const leafHook = (issue: any) => {
switch (issue._tag) {
case "InvalidType":
return "Expected different type";
case "InvalidValue":
return "Invalid value provided";
case "MissingKey":
return "Required property missing";
case "UnexpectedKey":
return "Unexpected property found";
case "Forbidden":
return "Operation not allowed";
case "OneOf":
return "Multiple valid options available";
default:
return "Validation error";
}
};
// Create a standard schema from a regular schema
const PersonSchema = Schema.Struct({
name: Schema.NonEmptyString,
age: Schema.Finite.check(Schema.isBetween({ minimum: 0, maximum: 150 })),
});
const standardSchema = Schema.toStandardSchemaV1(PersonSchema, {
leafHook,
});
// The standard schema can be used with any Standard Schema v1 compatible library
const validResult = standardSchema["~standard"].validate({
name: "Alice",
age: 30,
});
const invalidResult = standardSchema["~standard"].validate({
name: "",
age: 200,
});
if (validResult instanceof Promise || invalidResult instanceof Promise) {
throw new Error("Expected synchronous validation");
}
if ("value" in validResult) {
validResult.value; // => { name: "Alice", age: 30 }
}
invalidResult.issues?.map((issue) => issue.path); // => [["name"], ["age"]]
Type Parameter
S extends ConstraintDecoder<unknown, never>
Parameter Type
self S
options? { }

StandardSchemaV1<S["Encoded"], S["Type"]> & S

stable

4.0.0

TS
function fieldError(meta): string | undefined;

First readable TanStack string error or Standard Schema issue.

Parameter Type
meta { errors: readonly unknown[]; }
meta.errors readonly unknown[]

string | undefined


TS
type FormFieldsProps<V> = object;

Props accepted by FormFields.

Type Parameter
V extends FormValues
TS
model: SchemaFormModel<V>;
TS
optional names?: readonly keyof V & string[];

Render only these fields, in this order, without section headings.

TS
optional disabled?: boolean;

Disable every field, such as while an uncertain request is retried.


TS
function FormFields<V>(__namedParameters): (Element | null)[];

Render a schema form’s fields from its schema: every section in order, or only names (for placing fields in Screen cells or custom layouts).

Type Parameter
V extends Readonly<Record<string, FieldInput>>
Parameter Type
__namedParameters FormFieldsProps<V>

(Element | null)[]


TS
type FieldInput =
| string
| number
| boolean
| null
| undefined
| readonly string[]
| readonly File[];

The raw input one field holds: text, a number (or empty), a flag, or a set of chosen values or files. The schema turns it into the domain value at submit.


TS
type FormValues = Readonly<Record<string, FieldInput>>;

The raw values a schema form holds: one entry per field name.


TS
type FieldKind =
| "text"
| "email"
| "url"
| "tel"
| "textarea"
| "secret"
| "money"
| "date"
| "number"
| "select"
| "combobox"
| "file"
| "radio"
| "icon-radio"
| "checkbox"
| "switch"
| "checkboxes"
| "icon-checkboxes";

Every control a schema field can render as.


TS
type OptionAnnotation = object;

One choice’s presentation, keyed by its value in options.

TS
readonly optional label?: string;
TS
readonly optional description?: string;

A sentence under the label; radio options with one render as cards.

TS
readonly optional meta?: string;

A short readout on a radio card’s trailing edge, such as a price.

TS
readonly optional icon?: ReactNode;

A Sigil or App icon: choices with icons render as icon keys.

TS
readonly optional caption?: string;

The short legend on an icon key; label stays the accessible name.

TS
readonly optional disabled?: boolean;

TS
type FieldRenderProps<T> = object;

What a render annotation receives: the same wiring every built-in kind gets.

Type Parameter Default type
T extends FieldInput FieldInput
TS
readonly name: string;
TS
readonly label: string;
TS
readonly help: ReactNode;
TS
readonly value: T;
TS
readonly onBlur: () => void;

Mark the field visited, so its error shows.

void

TS
readonly error: string | undefined;

The visible error, after the person leaves the field or submits.

TS
readonly disabled: boolean;
TS
readonly id: string;

Put these on the control so the Field’s label, help and error name it.

TS
readonly aria-describedby: string | undefined;
TS
readonly aria-invalid: boolean;
TS
onChange(value): void;

Set the field’s raw value; validation runs as it would for a built-in kind.

Parameter Type
value T

void


TS
type FieldAnnotation<T> = object;

Presentation for one schema field. The schema stays the single source.

Type Parameter Default type
T extends FieldInput FieldInput
TS
readonly optional label?: string;

The visible label and accessible name; defaults to the humanized key.

TS
readonly optional help?: string;
TS
readonly optional kind?: FieldKind;

Overrides the kind inferred from the schema type.

TS
readonly optional placeholder?: string;
TS
readonly optional section?: string;

The sections key this field sits in; unsectioned fields come first.

TS
readonly optional order?: number;

Sort position within its section; fields keep schema order otherwise.

TS
readonly optional layout?: "stacked" | "row";

row puts the control opposite its label (a settings row).

TS
readonly optional required?: boolean;
TS
readonly optional optional?: boolean;

Marks an optional field in a mostly required form.

TS
readonly optional icon?: ReactNode;

A decorative Sigil or App icon before the label.

TS
readonly optional options?: Readonly<Record<string, string | OptionAnnotation>>;

Labels, help and icons for literal choices, keyed by value.

TS
readonly optional currency?: string;
TS
readonly optional unit?: string;
TS
readonly optional min?: number;
TS
readonly optional max?: number;
TS
readonly optional step?: number;
TS
readonly optional wrap?: boolean;
TS
readonly optional rows?: number;
TS
readonly optional maxLength?: number;
TS
readonly optional autoComplete?: string;
TS
readonly optional accept?: string;

Native file-picker filter; the schema owns file-type validation.

TS
readonly optional multiple?: boolean;
TS
readonly optional maxBytes?: number;

Per-file byte limit, enforced by the field’s schema check.

TS
readonly optional readOnly?: boolean;
TS
optional when(values): boolean;

Show the field only while this holds for the current raw values.

Parameter Type
values FormValues

boolean

TS
optional render(field): ReactNode;

The bailout: draw this field’s control yourself. Caps still owns the label, help, error, layout, validation and save bar.

Parameter Type
field FieldRenderProps<T>

ReactNode


TS
type SectionAnnotation = object;

A titled group of fields, declared on the struct.

TS
readonly title: string;
TS
readonly optional description?: string;

Holds a field annotation inside schema annotations (Effect or Zod).

TS
new FieldMeta(annotation): FieldMeta;
Parameter Type
annotation FieldAnnotation

FieldMeta

TS
readonly annotation: FieldAnnotation;

Holds the section list inside a struct’s annotations.

TS
new SectionsMeta(sections): SectionsMeta;
Parameter Type
sections Readonly<Record<string, SectionAnnotation>>

SectionsMeta

TS
readonly sections: Readonly<Record<string, SectionAnnotation>>;

TS
type FieldAnnotations = Record<`caps/form:${number}`, FieldMeta> & object;

Schema annotations for one field: Effect .annotate() or Zod .meta().

Name Type
title? string
description? string

TS
type SectionAnnotations = object;

Schema annotations for a struct’s sections.

TS
readonly caps/form: SectionsMeta;

TS
function field<T>(annotation): FieldAnnotations;

Annotate a schema field for forms. Works with Effect (Schema.String.annotate(field({ … }))) and Zod (z.string().meta(field({ … }))). label and help also become the schema’s title and description.

Type Parameter Default type
T extends FieldInput FieldInput
Parameter Type
annotation FieldAnnotation<T>

FieldAnnotations


TS
function sections(list): SectionAnnotations;

Annotate a struct with its sections, in display order.

Parameter Type
list Readonly<Record<string, SectionAnnotation>>

SectionAnnotations


TS
const Secret: brand<String, "Secret">;

A key or token: masked, never autofilled, with a reveal key.


TS
type ResolvedOption = object;

One choice, resolved for rendering.

TS
readonly value: string;
TS
readonly label: string;
TS
readonly description: string | undefined;
TS
readonly meta: string | undefined;
TS
readonly icon: ReactNode;
TS
readonly caption: string | undefined;
TS
readonly disabled: boolean;

TS
type ResolvedField = Omit<FieldAnnotation, "options" | "kind" | "help"> &
object;

One field, resolved from the schema for rendering.

Name Type
help string | undefined
name string
label string
kind FieldKind
options readonly ResolvedOption[]
optionalInSchema boolean
index number

TS
type ResolvedSection = object;

A section and its fields, in display order.

TS
readonly id: string | null;
TS
readonly title: string | undefined;
TS
readonly description: string | undefined;
TS
readonly fields: readonly ResolvedField[];

TS
type FormDescription = object;

Everything a form needs from its schema.

TS
readonly sections: readonly ResolvedSection[];
TS
readonly fields: readonly ResolvedField[];
TS
readonly defaults: FormValues;

TS
function describeSchema(schema): FormDescription;

Read a form’s fields, sections and empty defaults from its schema.

Parameter Type
schema | ZodType<unknown, unknown, $ZodTypeInternals<unknown, unknown>> | Top

FormDescription


TS
type FormSchema<V, Out> = Schema.Codec<Out, V> | z.ZodType<Out, V>;

A form schema: an Effect Schema.Struct (the house path) or a Zod object. V is the raw input the controls hold; Out is what the submit receives.

Type Parameter Default type
V extends FormValues FormValues
Out unknown

TS
function standardSchema<V, Out>(schema): StandardSchemaV1<V, Out>;

The schema as a Standard Schema validator for TanStack Form.

Type Parameter
V extends Readonly<Record<string, FieldInput>>
Out
Parameter Type
schema FormSchema<V, Out>

StandardSchemaV1<V, Out>


TS
function FormField<
TParentData,
TName,
TData,
TOnMount,
TOnChange,
TOnChangeAsync,
TOnBlur,
TOnBlurAsync,
TOnSubmit,
TOnSubmitAsync,
TOnDynamic,
TOnDynamicAsync,
TFormOnMount,
TFormOnChange,
TFormOnChangeAsync,
TFormOnBlur,
TFormOnBlurAsync,
TFormOnSubmit,
TFormOnSubmitAsync,
TFormOnDynamic,
TFormOnDynamicAsync,
TFormOnServer,
TSubmitMeta,
>(__namedParameters): Element;

TanStack field binding with Caps labels, descriptions, errors, and control ARIA.

Type Parameter
TParentData
TName extends string
TData
TOnMount extends FieldValidateOrFn<TParentData, TName, TData> | undefined
TOnChange extends FieldValidateOrFn<TParentData, TName, TData> | undefined
TOnChangeAsync extends FieldAsyncValidateOrFn<TParentData, TName, TData> | undefined
TOnBlur extends FieldValidateOrFn<TParentData, TName, TData> | undefined
TOnBlurAsync extends FieldAsyncValidateOrFn<TParentData, TName, TData> | undefined
TOnSubmit extends FieldValidateOrFn<TParentData, TName, TData> | undefined
TOnSubmitAsync extends FieldAsyncValidateOrFn<TParentData, TName, TData> | undefined
TOnDynamic extends FieldValidateOrFn<TParentData, TName, TData> | undefined
TOnDynamicAsync extends FieldAsyncValidateOrFn<TParentData, TName, TData> | undefined
TFormOnMount extends FormValidateOrFn<TParentData> | undefined
TFormOnChange extends FormValidateOrFn<TParentData> | undefined
TFormOnChangeAsync extends FormAsyncValidateOrFn<TParentData> | undefined
TFormOnBlur extends FormValidateOrFn<TParentData> | undefined
TFormOnBlurAsync extends FormAsyncValidateOrFn<TParentData> | undefined
TFormOnSubmit extends FormValidateOrFn<TParentData> | undefined
TFormOnSubmitAsync extends FormAsyncValidateOrFn<TParentData> | undefined
TFormOnDynamic extends FormValidateOrFn<TParentData> | undefined
TFormOnDynamicAsync extends FormAsyncValidateOrFn<TParentData> | undefined
TFormOnServer extends FormAsyncValidateOrFn<TParentData> | undefined
TSubmitMeta
Parameter Type
__namedParameters FieldComponentProps<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync, TFormOnServer, TSubmitMeta, { }> & Pick<FieldProps, | "required" | "optional" | "orientation" | "className" | "label" | "description">

Element


TS
type SubmissionState = object;

Values read by the submit action from TanStack’s form store.

TS
canSubmit: boolean;
TS
isSubmitting: boolean;

TS
type SubmitFooterProps = Omit<FormFooterProps, "children"> & object;

Footer presentation plus the submit action; TanStack owns availability and busy state.

Name Type Description
form object -
form.Subscribe() (props) => ReactNode TanStack’s reactive selector component.
label ReactNode -
disabled? boolean -
buttonProps? Omit<ButtonProps, "type" | "disabled" | "loading" | "children" | "onClick" | "asChild"> -

TS
function SubmitFooter(__namedParameters): Element;

Submit button subscribed to TanStack’s canSubmit/isSubmitting store state.

Parameter Type
__namedParameters SubmitFooterProps

Element


TS
type SubmitResult<V> =
| {
kind: "saved";
values?: V;
message?: string;
}
| {
kind: "refused";
error?: string;
fields?: Partial<Readonly<Record<keyof V & string, string>>>;
};

What a submit handler reports. Return nothing (or saved) when the change landed; return refused with a form-level error and/or per-field fields messages when the server said no. Field messages clear when that field changes; the form message clears on the next change anywhere.

Type Parameter
V extends FormValues
TS
{
kind: "saved";
values?: V;
message?: string;
}
Name Type Description
kind "saved" -
values? V The new baseline; defaults to the submitted values. Clear secrets here.
message? string Replaces the default “Saved” readout.

TS
{
kind: "refused";
error?: string;
fields?: Partial<Readonly<Record<keyof V & string, string>>>;
}

TS
type SchemaFormOptions<V, Out> = object;

Options accepted by useSchemaForm and an unbound SchemaForm.

Type Parameter
V extends FormValues
Out
TS
schema: FormSchema<V, Out>;

The single source: an Effect Schema.Struct (house path) or a Zod object. It validates raw input, parses the submitted value, and its annotations (field, sections) give labels, kinds, help, options, order and grouping.

TS
defaultValues: V;

The raw values to start from, such as the saved settings.

TS
onSubmit: (value, raw) =>
| Promise<SubmitResult<V> | undefined>
| Promise<void>
| SubmitResult<V>
| undefined;

Receives the parsed value, never the raw input.

Parameter Type
value Out
raw V

| Promise<SubmitResult<V> | undefined> | Promise<void> | SubmitResult<V> | undefined


TS
type Validator<V> = StandardSchemaV1<V, unknown>;

The schema as TanStack validates it: raw values in, any output.

Type Parameter
V

TS
type SchemaFormApi<V> = ReactFormExtendedApi<
V,
undefined,
Validator<V>,
undefined,
undefined,
undefined,
Validator<V>,
undefined,
undefined,
undefined,
undefined,
unknown
>;

The TanStack form a schema form owns: typed values, schema validators.

Type Parameter
V extends FormValues

TS
type SchemaFormModel<V> = object;

The model returned by useSchemaForm and read by SchemaForm, FormFields and SaveBar.

Type Parameter
V extends FormValues
TS
readonly description: FormDescription;

The fields, kinds and sections read from the schema.

TS
readonly form: SchemaFormApi<V>;

TanStack’s typed form: read values with useSelector(model.form.store, …).

TS
readonly error: string | null;

The last refused submit’s form-level message.

TS
readonly saved: string | null;

The last landed submit’s readout, until the next change.

TS
readonly discard: () => void;

Restore the baseline values and clear every message.

void

TS
readonly submit: () => Promise<void>;

Submit through the schema; the same path as the native submit event.

Promise<void>


TS
function useSchemaForm<V, Out>(options): SchemaFormModel<V>;

One form, declared by its schema. TanStack owns field state and timing; the schema owns validation and parses the submitted value; the handler only sees parsed data and reports saved or refused.

Type Parameter
V extends Readonly<Record<string, FieldInput>>
Out
Parameter Type
options SchemaFormOptions<V, Out>

SchemaFormModel<V>


TS
type SchemaFormStatus = object;

Live status for leave guards and save bars.

TS
dirty: boolean;

Values differ from the baseline.

TS
submitting: boolean;
TS
canSubmit: boolean;

Validation allows a submit right now.


TS
function useSchemaFormStatus<V>(model): SchemaFormStatus;

Subscribe to a schema form’s dirty and submitting state.

Type Parameter
V extends Readonly<Record<string, FieldInput>>
Parameter Type
model SchemaFormModel<V>

SchemaFormStatus


TS
type SchemaFormPresentation = object &
Omit<FormProps, "busy" | "onSubmit" | "noValidate" | "children">;

How a SchemaForm presents its actions and state.

Name Type Description
submitLabel? ReactNode The primary action’s label; defaults to “Save changes”.
discardLabel? ReactNode Show a Discard action while there are unsaved changes.
allowClean? boolean Keep the primary action available on a clean form (create forms).
footer? ReactNode Replaces the SaveBar, such as a footer with a retry key; null drops it.
children? ReactNode Replaces the generated field list, for custom layouts such as Screen cells: place fields with <FormFields model names={[…]} />.
disabled? boolean Disable every field, such as while an uncertain request is retried.

TS
type SchemaFormProps<V, Out> = SchemaFormPresentation &
| {
model: SchemaFormModel<V>;
}
| SchemaFormOptions<V, Out>;

Props accepted by SchemaForm: a model from useSchemaForm, or its options.

Type Parameter
V extends FormValues
Out

TS
function SchemaForm<V, Out>(props): Element;

A whole form from its schema: fields, sections, validation, busy state and the SaveBar. Pass schema, defaultValues and onSubmit, or a model from useSchemaForm when the page needs its status or a custom layout.

Type Parameter
V extends Readonly<Record<string, FieldInput>>
Out
Parameter Type
props SchemaFormProps<V, Out>

Element


TS
type SaveBarProps<V> = object &
Omit<FormFooterProps, "children" | "error" | "status">;

Props accepted by SaveBar.

Name Type Description
model SchemaFormModel<V> -
label ReactNode The primary action, such as “Save changes” or “Create Team”.
discardLabel? ReactNode Show a Discard action while there are unsaved changes.
allowClean? boolean Keep the primary action available on a clean form (create forms that may submit their defaults). By default a clean form has nothing to save.
dirtyLabel? ReactNode The quiet readout while there are unsaved changes.
buttonProps? Omit<ButtonProps, "type" | "disabled" | "loading" | "children" | "onClick" | "asChild"> -
Type Parameter
V extends FormValues

TS
function SaveBar<V>(__namedParameters): Element;

The form’s action row: the refused-submit error, a quiet “Unsaved changes” or “Saved” readout, an optional Discard, and the one primary submit.

Type Parameter
V extends Readonly<Record<string, FieldInput>>
Parameter Type
__namedParameters SaveBarProps<V>

Element