Skip to content

@ereo/forms

Signal-based form library for React with per-field reactivity. Each field gets its own signal from @ereo/state, so only the components bound to changed fields re-render. Validation rules derive their trigger behavior automatically -- no manual validateOn configuration needed.

Installation

bash
bun add @ereo/forms @ereo/state react

Quick Example

tsx
import { useForm, useField, useFormStatus, required, email } from '@ereo/forms'

function SignupForm() {
  const form = useForm({
    defaultValues: { email: '', password: '' },
    validators: {
      email: [required(), email()],
      password: [required(), minLength(8)],
    },
    onSubmit: async (values) => {
      await fetch('/api/signup', { method: 'POST', body: JSON.stringify(values) })
    },
  })

  const emailField = useField(form, 'email')
  const passwordField = useField(form, 'password')
  const { isSubmitting } = useFormStatus(form)

  return (
    <form onSubmit={(e) => { e.preventDefault(); form.handleSubmit() }}>
      <input {...emailField.inputProps} placeholder="Email" />
      {emailField.touched && emailField.errors[0] && (
        <span>{emailField.errors[0]}</span>
      )}

      <input {...passwordField.inputProps} type="password" placeholder="Password" />
      {passwordField.touched && passwordField.errors[0] && (
        <span>{passwordField.errors[0]}</span>
      )}

      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? 'Submitting...' : 'Sign Up'}
      </button>
    </form>
  )
}

Features

  • Per-field signals -- only the component using a changed field re-renders
  • Validation engine -- 20+ built-in validators with derive-don't-configure trigger behavior
  • Field arrays -- dynamic add/remove/swap/move for list-based fields
  • Wizard / multi-step forms -- step management with per-step validation
  • Schema adapters -- Zod, Valibot, and native ereoSchema DSL
  • Server actions -- progressive enhancement with ActionForm and createFormAction
  • Accessibility -- focus management, ARIA live announcements, error focus

Exports

Hooks

ExportDescription
useFormCreate a form instance with default values, validators, and submit handler
useFieldBind a single field -- returns value, errors, touched, and inputProps
useFieldArrayManage dynamic arrays (append, remove, swap, move, insert)
useWatchObserve field values reactively without registering the field
useFormStatusSubscribe to form-level status (submitting, dirty, valid)

Core

ExportDescription
FormStoreThe underlying store class holding per-field signals
createFormStoreFactory function to create a FormStore outside React
createValuesProxyES Proxy for natural property access (form.values.user.email)

Context

ExportDescription
FormProviderReact context provider for a form instance
useFormContextConsume the nearest FormProvider

Components

ExportDescription
FieldDeclarative field component with render prop
TextareaFieldPre-built textarea field
SelectFieldPre-built select field
FieldArrayDeclarative field array component

Validation

ExportDescription
requiredRequired field validator
emailEmail format validator
urlURL format validator
dateDate format validator
phonePhone number validator
minLength / maxLengthString length validators
min / maxNumeric range validators
patternRegExp pattern validator
number / integer / positiveNumeric type validators
customCustom sync validator
asyncCustom async validator (auto-validates on change with debounce)
matchesCross-field equality check
oneOf / notOneOfInclusion / exclusion validators
fileSize / fileTypeFile input validators
composeCompose multiple validators into one
whenConditional validator
vShorthand namespace re-exporting all validators (e.g. v.required(), v.email())

Schema Adapters

ExportDescription
zodAdapterAdapt a Zod schema for form-level validation
valibotAdapterAdapt a Valibot schema for form-level validation
isStandardSchemaType guard for Standard Schema V1 (~standard property)
standardSchemaAdapterExplicit adapter for Standard Schema V1-compliant validators
createSchemaValidatorGeneric schema adapter factory
ereoSchemaNative schema DSL (sync safeParse)
isEreoSchemaType guard for ereoSchema instances
formDataToObjectConvert FormData to a typed object

Wizard

ExportDescription
createWizardCreate a multi-step wizard instance
useWizardHook for wizard step navigation and state
WizardProviderReact context provider for a wizard
useWizardContextConsume the nearest WizardProvider
WizardStepRender the current step's content
WizardProgressStep progress indicator component
WizardNavigationNext / back / submit navigation buttons

Server Actions

ExportDescription
createFormActionCreate a server action handler with validation
ActionForm<form> wrapper for progressive enhancement
useFormActionHook to consume server action results
parseActionResultParse an ActionResult from a server response

Composition

ExportDescription
mergeFormConfigsDeep-merge multiple form configurations
composeSchemasCombine schemas for multi-section forms

Accessibility

ExportDescription
focusFirstErrorFocus the first field with a validation error
focusFieldProgrammatically focus a field by path
announcePush a message to an ARIA live region
announceErrorsAnnounce validation errors to screen readers
announceSubmitStatusAnnounce form submission outcome

Utilities

ExportDescription
getPathRead a nested value by dot-path
setPathImmutably set a nested value by dot-path
deepCloneStructured clone with fallback
deepEqualDeep equality check
parsePathParse "a.b[0].c" into path segments
flattenToPathsFlatten a nested object to dot-path entries

Released under the MIT License.