21

useForm

Create a typed reactive form from a Standard Schema-compatible object schema. Full configuration and instance reference.

useForm creates the form instance that owns values, errors, field instances, and submit state. Call it in a Vue setup context (<script setup> or setup()), so its timers and watchers are cleaned up when the component unmounts.

import { useForm } from 'notform'
import { z } from 'zod'

const form = useForm({
  initialValues: { displayName: '', email: '' },
  onSubmit(data) {
    console.log(data)
  },
  schema: z.object({
    displayName: z.string().min(1),
    email: z.email(),
  }),
})

In Nuxt, useForm is auto-imported. See the Nuxt module guide.

Configuration

schema
MaybeRefOrGetter<TSchema> required
A Standard Schema-compatible object schema. May be a value, a ref, or a getter. It is read each time validation runs.
initialValues
DeepPartial<SchemaInput<TSchema>>
Starting values and the baseline for isDirty and reset(). May be partial, but provide a value for every bound field.
initialErrors
ValidationIssue[]
Issues shown before the first validation. An issue without a path is form-level.
onSubmit
(data: SchemaOutput<TSchema>) => void | Promise<void>
Called after the whole form validates. The argument is the parsed schema output.

Returned instance

The returned object is reactive. Read members directly, for example form.isDirty.

State

MemberTypeDescription
valuesSchemaInput<TSchema>Live input values. Editable directly, through setValue, or through field models.
errorsValidationIssue[]Current issues. Empty when nothing is wrong.
isDirtybooleanValues differ from the baseline.
isTouchedbooleanA field blurred or a submit was attempted.
isSubmittedbooleanAt least one submit was attempted.
isSubmittingbooleanValidation or onSubmit is running.
isValidatingbooleanA validation is running.
isValidbooleanThe error list is empty. Does not validate.
submitCountnumberSubmit attempts since the last reset.
resetCountnumberNumber of resets.

Fields

MemberDescription
field(path, config?)Get or create the cached field for a typed input path.
arrayField(path, config?)Get or create the cached array field for a typed array path.

The first call for a path creates the field and reads config. Later calls return the same instance and ignore any config. See Validation.

Actions

MemberDescription
submit(event?)Validate the form and call onSubmit if it passes. Prevents the event's default action. Ignored while a submit is running. Rejects if onSubmit throws.
validate()Validate the whole form without calling onSubmit. Replaces all errors. Resolves with { value } or { issues }.
reset(values?, errors?)Restore the baseline, or replace it when arguments are given. Clears touched and submit state.
setError(issue)With a path, replaces errors at that path. Without, appends a form-level error.
setValue(path, value)Write a typed input value. Does not validate.

Typed paths and values

Paths use dot notation and are checked against the schema input. form.field('address.city') targets a nested value, and form.arrayField('contacts') targets an array. Values in form.values use the input type, and onSubmit receives the output type. See Schema input and output and TypeScript.

Notes

  • Call useForm once per form. Each call creates an independent form.
  • Outside a Vue setup context, cleanup on unmount does not run.
  • Changing a reactive schema discards in-flight validations but does not re-validate.
  • The returned type is UseFormInstance<TSchema>, the public contract documented here.
Copyright © 2026 NotForm
Published under MIT License