Skip to content

How it compares

Before comparing features, answer this:

Does your form definition live in your frontend code, or does it arrive at runtime as data?

That single question splits the field cleanly, and it matters more than any feature list.

Use React Hook Form, TanStack Form or Formik.

They’re mature, widely used, well documented, and they let you express a form in TypeScript with full type inference — validation schemas from Zod or Yup, compile-time errors when a field name is wrong, and no indirection between the code and the form.

driven-form is a worse choice for this. You’d be paying the cost of a runtime schema — losing static types over field names, gaining a layer of indirection — for no benefit. If your forms change on the same cadence as your code, put them in your code.

Now the comparison is with JSON Forms, react-jsonschema-form, Formily and SurveyJS — and driven-form belongs in that group.

The rest of this page is about the differences within it.

The schema is designed for forms, not derived from a data shape

Section titled “The schema is designed for forms, not derived from a data shape”

JSON Schema describes the shape of data. It was built for validation, and form rendering was layered on afterwards — which is why JSON Forms uses a second UI Schema to say how the data should look, and why RJSF needs uiSchema and widget overrides for anything beyond the defaults.

driven-form’s schema describes a form: a node has an order, a show expression, a calculateValue. Conditional logic lives on the field it governs, not in a parallel document.

The cost is real and worth stating: it isn’t a standard. You can’t point it at an OpenAPI document. A JSON Schema adapter is on the roadmap and not built. If standards compliance matters to you, JSON Forms and RJSF are ahead.

A field re-renders only when its own value, its own error, or a declared dependency changes. That’s checked in the test suite rather than asserted in a README, and you can watch it: the playground’s Renders tab counts every field’s renders live. Type into one field of a 45-field form and exactly one field re-renders.

Most form libraries care about this. Few make it a contract you can inspect.

A chain of derived fields — quantity × price → subtotal → discount → taxable → total — resolves inside a single data write, not one render pass per link. The dependency graph is built once at parse time and evaluated in topological order, so a diamond evaluates once and a cycle is caught and reported at parse time instead of silently failing.

The practical consequence matters more than the render count: form data is consistent the moment you write to it, whether or not the dependent fields are mounted.

driven-form ships zero components. That’s stricter than “headless” usually means — there’s no default theme to override, no styling to reset. You write your inputs once and register them by type name.

The showcase demonstrates the consequence: three completely different component kits rendering the same schema, swapped live, with values and validation state surviving the swap.

This is a real cost on day one. RJSF and JSON Forms give you working Material UI forms immediately; driven-form gives you nothing until you write a text input. We think that trade is right for a long-lived application and wrong for a prototype.

Stated plainly, because you’ll find out anyway:

  • It’s pre-1.0. Version 0.1.0, one primary author, API may still shift. JSON Forms and RJSF have years of production use and far larger communities.
  • No standard-schema import. No OpenAPI or JSON Schema adapter yet.
  • No visual form builder. SurveyJS has a mature drag-and-drop editor. If non-developers need to build forms rather than have them generated, that’s a significant gap.
  • Missing state APIs. No isDirty / touched / resetForm() yet, so “unsaved changes” guards need hand-rolling. No watch() subscription API.
  • No cascading async selects. country → state → city with server-loaded options is something every consumer currently hand-rolls.
  • No i18n. Validation messages have no catalogue or interpolation.
  • Expression language limitations. % is the field delimiter and can’t be escaped, so modulo is unavailable and a literal % inside a string breaks variable extraction. Control-character escapes (\n) don’t work in expression strings.
  • No published benchmark. The render contract is test-enforced, but there are no comparative performance numbers against other libraries. Claims here are about the engine’s own behaviour, not about beating anyone.
  • SSR/RSC is unaddressed. Registration happens in client-only effects; the boundary isn’t documented and first paint depends on hydration.

Most of these are tracked in V2-TODO.md.

Forms in codedriven-formJSON Schema toolsSurveyJS
Form definitionTypeScriptRuntime JSONRuntime JSON SchemaRuntime JSON
Change a form without deployingNoYesYesYes
Standard schema formatn/aNoYesNo
Ships UI componentsNoNoYesYes
Visual builderNoNoNoYes
Static types over field namesYesNoPartialNo
MaturityHighPre-1.0HighHigh

Nothing in that table is a score. Every row is a trade, and which way it should go depends on your situation.

  • Your forms change when your code changes → React Hook Form or TanStack Form
  • You need full type inference over field names → React Hook Form or TanStack Form
  • You already have JSON Schema or OpenAPI definitions → JSON Forms or RJSF
  • Non-developers need to build forms visually → SurveyJS
  • You need working styled forms today with no component work → RJSF or JSON Forms
  • You can’t take a dependency on a pre-1.0 library → wait, or vendor it
  • Forms change more often than your release cycle
  • Different tenants, regions or products need different fields from the same code
  • A backend, a CMS, or a model is the thing that decides what the form asks
  • You have a design system, and every library’s default components are something you’d have to fight
  • You have long, conditional forms where render cost and derived values actually matter

If none of those describe you, one of the libraries above will serve you better, and we’d rather you used it.