Headless React form engine — your backend defines the form, your frontend just renders it.
Conditional fields, validation, calculated values and repeaters live in a JSON schema your backend controls. Change a form without a frontend deploy.
{
"name": "companyName",
"type": "text",
"label": "Company name",
"show": "%hasCompany% == 'Yes'",
"required": "%hasCompany% == 'Yes'"
}That's the entire "add a conditional field" ticket. No frontend PR.
| Playground | Edit a schema, watch the form change. Nothing to install. |
| Quickstart | Working in about five minutes. |
| Showcase | Seven real forms — conditionals, repeaters, async checks, live design swapping. |
| How it compares | An honest look at when to use something else instead. |
npm install driven-formimport { DrivenForm, createFieldRegistry } from 'driven-form/react'
// Write each field component once. The engine wires up value, error,
// show/required/disabled, and onChange/onBlur for you.
const registry = createFieldRegistry()
registry.register('text', TextInput)
<DrivenForm
schema={schemaFromYourApi}
fieldRegistry={registry}
onSave={({ data }) => api.submit(data)}
>
{({ handleContinue }) => <button onClick={handleContinue}>Submit</button>}
</DrivenForm>Everything after that — conditionals, cross-field validation, calculated values, async checks, repeaters — is a schema change, not a code change.
- The library owns logic and state. You own every pixel. It ships no UI at
all, so a
TextInputyou write on day one never needs touching again. - A small expression language driving
show,required,disabledandcalculateValue— evaluated by a sandboxed AST interpreter, nevereval(). - Calculated values that settle in one write, through a dependency graph built when the schema is parsed. A four-deep chain costs one render pass.
- Repeaters as a first-class field, with per-row scoped validation, row
expressions, and cross-row aggregates like
sum(%rows%, 'amount'). - A render-count contract, enforced by tests. A field re-renders only when its own value, its own error, or a declared dependency changes — you can watch it happen in the playground's Renders tab.
- Tree-shakable by construction. Repeater support only enters your bundle if you import it, guarded by a check that fails the build otherwise.
git clone https://github.com/vineetpjp/driven-form
cd driven-form/examples/plain-html # smallest complete integration
npm install && npm run devexamples/basic is the kitchen sink: conditional sections, async validation, a cap table, cross-row aggregates and a 95-field performance page.
Pre-1.0. The core engine, expression language, registry, validation, lazy fields, repeaters and cross-row aggregates are implemented and covered by 324 tests. The API may still shift before a 1.0 tag — see V2-TODO.md for what's next and CHANGELOG.md for what's changed.
MIT