What it is
driven-form is a headless React form engine. Your backend sends a JSON schema describing the form; your frontend renders it with components you wrote once.
The split
Section titled “The split”The library owns logic and state. Which fields show, which are required, which are disabled, what values are derived from other values, what’s valid, and how array rows behave.
You own every pixel. The engine ships no UI at all. It hands your component a value, an error, and a change handler, and gets out of the way.
That’s the whole contract. A TextInput you write on day one never needs
touching again, no matter how the form changes.
Where the logic lives
Section titled “Where the logic lives”Conditions are expressions inside the schema:
%fieldName% truthy check%country% == 'IN' equals%age% > 18 && %hasConsent% boolean logic%price% * %quantity% calculated valuesum(%rows%, 'amount') across repeater rowsThey drive show, required, disabled and calculateValue on any field, and
they’re evaluated by a sandboxed AST interpreter — never eval().
What you get for free
Section titled “What you get for free”- Conditional fields without a single
useStatein your form code - Validation, sync and async, with per-rule
validateOncontrol - Calculated values that settle a whole dependency chain in one render pass
- Repeaters — array fields with add/remove/move, scoped per-row validation, and render isolation between rows
- A render-count contract: a field re-renders only when its own value, its own error, or a declared dependency changes. Enforced by tests, not by hope.
When it fits
Section titled “When it fits”Reach for driven-form when forms change more often than your release cycle, when different tenants or products need different fields, or when someone who isn’t a frontend engineer — a PM, a CMS, an LLM — should be able to change a form.
It’s less useful for a single hardcoded login form. Two fields and no conditions don’t need an engine. And if your forms live in your code and change when your code changes, a library like React Hook Form will serve you better — how it compares goes through that honestly.
Status
Section titled “Status”Pre-1.0. The core engine, expression language, registry, validation, lazy fields and repeaters are implemented and covered by 271 tests. The API may still shift before a 1.0 tag.