Skip to content

FormEngine reference

FormEngine holds values, errors, visibility, and step state without depending on a UI framework.

Constructor

ts
import { FormEngine } from '@formhaus/core';

const engine = new FormEngine(definition, initialValues, {
  validators,
  onStepValidate,
});

Both initialValues and the options object are optional. Values belonging to hidden fields or hidden steps are removed during construction.

State

PropertyTypeDescription
valuesRecord<string, unknown>Current field values
errorsRecord<string, string>Errors attached to visible fields
topLevelErrorsstring[]Errors for missing or hidden fields
fieldLoadingRecord<string, boolean>Per-field loading state
stepValidatingbooleanWhether onStepValidate is running
currentStepIndexnumberZero-based index in the visible step list
visibleFieldsFormField[]Visible fields on the current step, or all visible fields in a single-step form
visibleStepsFormStep[]Steps whose conditions currently pass
currentStepFormStep | nullCurrent visible step
isFirstStep / isLastStepbooleanCurrent navigation position
canGoNextbooleanWhether current-step validation passes
progress{ current: number; total: number }One-based progress through visible steps
isMultiStepbooleanWhether the definition uses steps

Values and validation

MethodReturnsDescription
setValue(key, value)voidSets a value, clears its error, and reconciles dependent visibility
setErrors(errors)voidReplaces existing errors and navigates to the first visible field with an error
setFieldLoading(key, loading)voidUpdates loading state for one field
validate()Record<string, string>Validates all visible fields
validateField(key)string | nullValidates one visible field
getSubmitValues()Record<string, unknown>Returns values for visible fields only
reset(values?)voidResets values, errors, loading state, validation state, and navigation

reset() also removes values hidden by the new reset values. Pending async step-validation results are discarded.

MethodReturnsDescription
nextStep()booleanValidates and advances without running onStepValidate
nextStepAsync()Promise<boolean>Validates, awaits onStepValidate, and advances when no errors are returned
prevStep()voidMoves to the previous visible step
goToStepWithField(key)voidMoves to the visible step containing a field

See Async step validation for an onStepValidate example.

Subscriptions

Use the general subscription when a consumer needs the entire engine state:

ts
const unsubscribe = engine.subscribe(() => {
  render(engine.values, engine.errors);
});

const version = engine.getSnapshot();

For renderers, the granular subscriptions avoid updating unrelated fields:

MethodDescription
subscribeField(key, listener)Runs the listener when that field's value, error, or loading state changes
getFieldSnapshot(key)Returns that field's revision number
subscribeStructure(listener)Runs the listener when visible fields, visible steps, or navigation changes
getStructureSnapshot()Returns the structure revision number

Each subscribe method returns an unsubscribe function. Snapshot methods return stable numbers until the corresponding state changes, so they can be passed to external-store APIs such as React's useSyncExternalStore.