Integrations
BlueForm is fully headless — it ships no styles and has no opinion on how your fields look. This makes it compatible with any React UI library without adapters, plugins, or special configuration.
Sample form
Every recipe in this section builds the same form: four field types (text, longText, select, checkbox), a nested settings section, and an addresses array field.
This config describes what the form collects. It has zero knowledge of the UI library — swapping libraries almost never touches it.
What changes, what doesn't
Migrating from one UI library to another basically means rewriting field components and nothing else.
Adapting event signatures
Different libraries expose different onChange signatures — some return the value directly, others wrap it in an event object, others use a custom object. BlueForm doesn't impose any convention. onChange comes from RHF's useController, which accepts both a native event and a plain value:
For better maintainability, always pass a clean value explicitly:
Bring your own library
Don't see your library here? The pattern is always the same:
- Call
useFieldinside your field component and destructure what you need - Map
value→ the library's value prop, callonChange?.(value)inside the library's change handler - Use
errorMessage,label,disabled,visibleto wire up the rest
If you can render an input, you can integrate with BlueForm.
Validation libraries
BlueForm delegates validation entirely to React Hook Form's resolver system, which means any library supported by @hookform/resolvers works without any changes to your field components or form config. Define your schema using your preferred library, then pass its resolver via formOptions:
When a resolver is provided, validation is fully handled by the schema — no rules needed on any field. Your config becomes purely structural: field type, label, and props only.
Schema-level defaults (e.g. .default() in Zod) are not picked up by React Hook Form at initialization — the resolver only runs at validation time, not at mount. Always set initial values via defaultValues or the defaultValue prop on individual fields.

