Form Wire
API Reference

createFormWire

Create a typed form wire from a Zod schema

createFormWire is the primary API for building forms. It takes a Zod schema and optional config, returning typed components.

Signature

function createFormWire<TSchema extends SupportedFormSchema>(
  schema: TSchema,
  config?: FormWireConfigForSchema<TSchema>,
): CreatedFormWire<TSchema>;

Parameters

schema

A Zod object schema or discriminated union schema:

z.object({ name: z.string(), email: z.email() })

config

Optional field configuration:

{
  fields: {
    fieldName: {
      label?: string;
      description?: string;
      placeholder?: string;
      component?: string;
      hidden?: boolean | ((values) => boolean);
      readOnly?: boolean | ((values) => boolean);
      disabled?: boolean | ((values) => boolean);
      requiredWhenVisible?: (values) => boolean;
      asyncValidate?: async (value, values) => string | string[] | undefined;
      array?: {
        addLabel?: string;
        removeLabel?: string;
        moveUpLabel?: string;
        moveDownLabel?: string;
        itemLabel?: string | ((index: number) => string);
      };
    },
  },
}

Return Value

Returns a CreatedFormWire<TSchema> with these components:

ComponentDescription
FormAuto-renders all fields. Props: action, mapper?, defaultValues?, validationTiming?, draftPersistence?
WizardMulti-step form. Props: action, nextLabel?, previousLabel?, submitLabel?, plus same as Form
FieldRenders a single named field. Props: name, hidden?, readOnly?, disabled?, className?
FieldsRenders a list of named fields. Props: names?, className?
StepDeclares a wizard step. Props: title, children?
WhenConditional rendering. Props: field? + equals? or matches?, children?, fallback?

Type Safety

Field names are typed:

const Contact = createFormWire(z.object({
  name: z.string(),
  email: z.email(),
}));

// ✅ Valid
<Contact.Field name="name" />
<Contact.Field name="email" />

// ❌ TypeScript error
<Contact.Field name="phone" />

Example

const Contact = createFormWire(
  z.object({
    name: z.string().min(1, "Required"),
    email: z.email(),
  }),
  {
    fields: {
      name: { label: "Name", placeholder: "Ada Lovelace" },
      email: { label: "Email", placeholder: "ada@form.dev" },
    },
  },
);

function MyForm() {
  return (
    <Contact.Form action={submitContact}>
      <Contact.Field name="name" />
      <Contact.Field name="email" />
    </Contact.Form>
  );
}

On this page