Forms are just data.
Hand Easy Forms an array of question objects. It owns rendering, validation, conditional logic, multi-step wizards, and submission — so you don't wire any of it by hand.
See it in motion
Write the schema. Watch the form build itself.
The pane on the right is the genuine library — the same engine you ship. Switch presets to see conditional logic and derived values react live.
const schema: FormSchema = {title: 'Create your account',groups: [{layout: 'grid',gridCols: 2,questions: [{key: 'firstName',label: 'First name',control: 'text',placeholder: 'Ada',validators: { required: true, minLength: 2 },},{key: 'lastName',label: 'Last name',control: 'text',placeholder: 'Lovelace',validators: { required: true },},],},{questions: [{key: 'email',label: 'Email',control: 'email',placeholder: 'you@example.com',validators: { required: true, email: true },},{key: 'plan',label: 'Plan',control: 'dropdown',placeholder: 'Choose a plan',options: [{ value: 'free', label: 'Free' },{ value: 'pro', label: 'Pro — $9/mo' },{ value: 'team', label: 'Team — $29/mo' },],validators: { required: true },},],},],};
Why Easy Forms
A higher-level form library, not another hook
Everything a production form needs — declarative, typed, and accessible — without the boilerplate.
Schema-driven
One array of question objects is the source of truth. No useForm, register, or Controller wiring.
Headless + swappable renderers
The engine is UI-agnostic. Ship the shadcn registry or drop in your own design system.
Type-narrowed validation
Validators are typed by the field value — minLength on a checkbox is a compile error.
Three dependency kinds
propsDependsOn, valueDependsOn, resetDependsOn cover every dynamic prop, derived value, and reset.
Multi-step wizards
Per-step validation, step-level visibility, and resumable localStorage persistence out of the box.
Surgical re-renders
A custom topic-based store wakes only the field you changed — not the whole form.
Plugin lifecycle
onInit / onChange / onSubmit / onDestroy hooks. Logger and autosave ship built-in.
Extend without forking
Module augmentation adds custom controls, validators, and dependency kinds — fully typed.
How it compares
Built-in where others leave you wiring
Easy Forms owns the workflow. Honest comparison — others are excellent libraries, with a different scope.
| Capability | Easy Forms | React Hook Form | Formik | Hand-rolled |
|---|---|---|---|---|
| Schema as the source of truth | ||||
| Conditional logic built-in | manual | manual | ||
| Derived / computed values | manual | |||
| Multi-step wizard + persistence | ||||
| Accessible renderers by default | ||||
| Per-field surgical re-renders | ||||
| Swappable renderer registry | manual | manual |
Real, interactive
Every example is a working form
No screenshots. No mocks. These run @easy-forms/core with the shadcn renderer registry, right here.
Performance
One field changes. One field re-renders.
Easy Forms is built on a custom external store with topic-based, per-field subscriptions via useSyncExternalStore. Typing in one input wakes only that field's subscribers and the form-state subscriber — not the entire form. Hundred-field forms stay smooth without manual memoization.
24 fields rendered — editing one repaints just the highlighted cell.
Enterprise-ready
Adopt with confidence
A predictable, typed core your team can reason about — plus a transparent roadmap for the governance features large orgs ask for.
Available today
- Fully typed schema & validators (TS strict)
- Headless control — own your markup & a11y
- Plugin hooks for autosave, logging, audit trails
- Extend with custom controls, validators, deps
- Dual ESM/CJS builds, tree-shakeable, MIT
On the roadmap
- SSO/SAML field packs
- Audit-log plugin
- SOC 2 & compliance docs
- Priority support SLAs
Ship your next form in minutes.
Install the packages, paste a schema, render a form. The 5-minute quick start gets you to a working, validated, accessible form.