Skip to main content
The createForm function creates and manages forms in Solid applications using TanStack Form.

Import

import { createForm } from '@tanstack/solid-form'

Signature

function createForm<
  TParentData,
  TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
  TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
  TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
  TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
  TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
  TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
  TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
  TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
  TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
  TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>,
  TSubmitMeta,
>(
  opts?: () => FormOptions<
    TParentData,
    TFormOnMount,
    TFormOnChange,
    TFormOnChangeAsync,
    TFormOnBlur,
    TFormOnBlurAsync,
    TFormOnSubmit,
    TFormOnSubmitAsync,
    TFormOnDynamic,
    TFormOnDynamicAsync,
    TFormOnServer,
    TSubmitMeta
  >,
): SolidFormExtendedApi<...>

Parameters

opts
() => FormOptions<TFormData>
A function that returns the configuration object for the form. The function is reactive and will update the form when dependencies change.
opts().defaultValues
TFormData
Initial values for the form fields.
opts().onSubmit
(values: FormSubmitData<TFormData>) => void | Promise<void>
Callback function called when the form is submitted.
opts().validators
FormValidators<TFormData>
Validation functions for the form.
opts().validators.onChange
FormValidateOrFn<TFormData>
Validator that runs on every change.
opts().validators.onChangeAsync
FormAsyncValidateOrFn<TFormData>
Async validator that runs on change with debouncing.
opts().validators.onBlur
FormValidateOrFn<TFormData>
Validator that runs when the form loses focus.
opts().validators.onMount
FormValidateOrFn<TFormData>
Validator that runs when the form is mounted.

Return Value

api
SolidFormExtendedApi<TFormData>
The form API instance with Solid-specific extensions.
Field
FieldComponent<TFormData>
A Solid component for rendering individual form fields.
createField
CreateField<TFormData>
A function for creating and managing individual fields.
useStore
(selector?) => () => TSelected
A function for subscribing to form state changes.
Subscribe
Component
A component for subscribing to form state.
handleSubmit
() => void
Function to trigger form submission.
reset
() => void
Function to reset the form to its initial state.
state
FormState<TFormData>
Current state of the form including values, errors, and validation status.

Usage Example

Basic Form

import { createForm } from '@tanstack/solid-form'
import { Show } from 'solid-js'

interface FormData {
  firstName: string
  lastName: string
}

function App() {
  const form = createForm<FormData>(() => ({
    defaultValues: {
      firstName: '',
      lastName: '',
    },
    onSubmit: ({ value }) => {
      console.log('Form submitted:', value)
    },
  }))

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault()
        e.stopPropagation()
        form.handleSubmit()
      }}
    >
      <form.Field
        name="firstName"
        validators={{
          onChange: ({ value }) =>
            !value
              ? 'A first name is required'
              : value.length < 3
                ? 'First name must be at least 3 characters'
                : undefined,
        }}
      >
        {(field) => (
          <div>
            <label for={field().name}>First Name:</label>
            <input
              id={field().name}
              name={field().name}
              value={field().state.value}
              onInput={(e) => field().handleChange(e.currentTarget.value)}
              onBlur={() => field().handleBlur()}
            />
            <Show when={field().state.meta.isTouched && field().state.meta.errors.length > 0}>
              <div style={{ color: 'red' }}>{field().state.meta.errors[0]}</div>
            </Show>
          </div>
        )}
      </form.Field>

      <form.Subscribe selector={(state) => ({ canSubmit: state.canSubmit, isSubmitting: state.isSubmitting })}>
        {(state) => (
          <button type="submit" disabled={!state().canSubmit}>
            {state().isSubmitting ? '...' : 'Submit'}
          </button>
        )}
      </form.Subscribe>
    </form>
  )
}

Form with Array Fields

import { createForm } from '@tanstack/solid-form'
import { Index, Show } from 'solid-js'

function App() {
  const form = createForm(() => ({
    defaultValues: {
      people: [] as Array<{ name: string; age: number }>,
    },
    onSubmit: ({ value }) => {
      alert(JSON.stringify(value))
    },
  }))

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault()
        e.stopPropagation()
        form.handleSubmit()
      }}
    >
      <form.Field name="people">
        {(field) => (
          <div>
            <Show when={field().state.value.length > 0}>
              <Index each={field().state.value}>
                {(_, i) => (
                  <form.Field name={`people[${i}].name`}>
                    {(subField) => (
                      <div>
                        <label>
                          <div>Name for person {i}</div>
                          <input
                            value={subField().state.value}
                            onInput={(e) => {
                              subField().handleChange(e.currentTarget.value)
                            }}
                          />
                        </label>
                      </div>
                    )}
                  </form.Field>
                )}
              </Index>
            </Show>

            <button
              onClick={() => field().pushValue({ name: '', age: 0 })}
              type="button"
            >
              Add person
            </button>
          </div>
        )}
      </form.Field>
      <button type="submit">Submit</button>
    </form>
  )
}

Form with useStore

import { createForm } from '@tanstack/solid-form'
import { Show } from 'solid-js'

function App() {
  const form = createForm(() => ({
    defaultValues: {
      username: '',
    },
    onSubmit: ({ value }) => {
      console.log(value)
    },
  }))

  const canSubmit = form.useStore((state) => state.canSubmit)
  const isSubmitting = form.useStore((state) => state.isSubmitting)
  const errors = form.useStore((state) => state.errors)

  return (
    <div>
      <form onSubmit={(e) => {
        e.preventDefault()
        form.handleSubmit()
      }}>
        {/* Form fields */}
        <button type="submit" disabled={!canSubmit()}>
          {isSubmitting() ? 'Submitting...' : 'Submit'}
        </button>
      </form>
      
      <Show when={errors().length > 0}>
        <div>Form has errors</div>
      </Show>
    </div>
  )
}

See Also

Build docs developers (and LLMs) love