useForm + JSX with a single <FormViewer>
component.
Last reviewed: April 2026.
This guide maps React Hook Form concepts directly to FormEngine equivalents, with before/after code
for the most common patterns. It’s written for incremental migration — you can move one form at a
time.
FormEngine Core is open-source on GitHub. For the full
comparison of architectures, see FormEngine vs React Hook
Form.
Why teams migrate
React Hook Form is an excellent library for code-defined forms. Teams typically migrate to FormEngine when:- Forms need to be configurable at runtime without a deploy (schemas stored in a database)
- Non-developers need to edit forms via a visual designer
- Multiple apps share the same form definitions
- Forms require complex conditional logic that’s tedious to maintain in JSX
Concept mapping
| React Hook Form | FormEngine |
|---|---|
useForm() | <FormViewer form={schema}> |
register('fieldName') | Component entry in JSON schema |
handleSubmit(fn) | onActionEventAsync with submit event |
Controller | Any component type in schema |
formState.errors | form.errors in expressions |
watch('field') | form.data.field in renderWhen |
useFieldArray | Repeater component in schema |
setValue | setValues action |
| Yup/Zod resolver | Built-in validators or custom Zod validator |
defaultValues | defaultValue prop on components |
Before/after: basic form
React Hook Form:Before/after: validation with Zod
React Hook Form + Zod resolver:Before/after: conditional fields
React Hook Form:renderWhen skips validation on hidden fields automatically — no need to conditionally
register or unregister. See Conditional fields tutorial.
Before/after: field arrays (repeating sections)
React Hook FormuseFieldArray:
Repeater:
formData.attendees = [{ name: '...', email: '...' }, ...].
Before/after: programmatic value setting
React Hook FormsetValue:
setValues action:
Migration strategy
Incremental approach (recommended):- Pick a single form to migrate first — ideally one that changes frequently.
- Install FormEngine alongside React Hook Form:
npm install @react-form-builder/core @react-form-builder/components-material-ui - Translate the form to a JSON schema.
- Replace the RHF
<form>with<FormViewer>. - Move validation rules to the schema.
- Move the
onSubmithandler toonActionEventAsync. - Verify and ship.
- Repeat for the next form.
What doesn’t migrate cleanly
Render-prop patterns: RHF’sController render prop and useController hook let you integrate
arbitrary controlled components. In FormEngine, you register a component type once and use it
everywhere — there’s no per-instance render prop. If you have one-off custom inputs, you’ll need to
wrap them as custom components.
Complex watch chains: watch in RHF lets you drive arbitrary React code from field values. In
FormEngine, reactive logic goes into renderWhen, actions, and computed properties — powerful but
different in structure. Very complex watch-driven UI logic may take time to re-express in the schema
model.
RHF DevTools: React Hook Form has a Chrome extension for inspecting form state. FormEngine
doesn’t have a browser extension, but form state is accessible via FormViewerRef.getFormData() for
debugging.
Next steps
- Dynamic form from JSON tutorial — FormEngine from scratch
- Validation with Zod — migrate Zod resolver patterns
- Conditional fields tutorial — migrate
watch-based conditional rendering - Validation reference — full built-in validator list
- Actions and events reference —
setValues, computed values, submit - Workflow approval forms — real-world case: what post-migration FormEngine looks like in production
- FormEngine vs React Hook Form — architecture comparison
- FormEngine on GitHub — MIT source code