Validation is usually a mix of fast local UX rules and one stronger source of truth for business constraints.
- Start with fluent builder rules when the rule clearly belongs to one field
- Add conditional required or visibility rules in the schema instead of scattering conditions through JSX
- Use a bridge when Zod, Yup, Joi, or Valibot already owns the canonical validation contract
- Use async options when a field depends on remote search or lookup data
Builder rules and cross-field logic
This is the fastest path for forms whose rules live mostly in the frontend or belong to one field at a time.
ValidationRules.tsxtsx
| 1 | const schema = { |
| 2 | email: field.email('Work email').required().trim().lowercase(), |
| 3 | password: field.password('Password').required().strong(), |
| 4 | confirmPassword: field |
| 5 | .password('Confirm password') |
| 6 | .required() |
| 7 | .sameAs('password', 'Passwords must match'), |
| 8 | accountType: field.select('Account type').options([ |
| 9 | { label: 'Personal', value: 'personal' }, |
| 10 | { label: 'Company', value: 'company' }, |
| 11 | ]).required(), |
| 12 | companyName: field |
| 13 | .text('Company name') |
| 14 | .visibleWhen('accountType', 'company') |
| 15 | .requiredWhen('accountType', 'company') |
| 16 | .clearOnHide(), |
| 17 | } |
| 18 | |
| 19 | const form = useFormBridge(schema, { |
| 20 | validateOn: 'onBlur', |
| 21 | revalidateOn: 'onChange', |
| 22 | }) |
Schema adapters
Use a bridge when the backend or another package already shares a validation schema with the frontend.
zod-bridge.tsts
| 1 | import { z } from 'zod' |
| 2 | import { field, useFormBridge, zodBridge } from '@runilib/react-formbridge' |
| 3 | |
| 4 | const schema = { |
| 5 | email: field.email('Email').required(), |
| 6 | password: field.password('Password').required(), |
| 7 | } |
| 8 | |
| 9 | const zodSchema = z.object({ |
| 10 | email: z.string().email(), |
| 11 | password: z.string().min(8), |
| 12 | }) |
| 13 | |
| 14 | const form = useFormBridge(schema, { |
| 15 | validatorBridge: zodBridge(zodSchema), |
| 16 | }) |
Async lookups and remote options
Remote search belongs in a different lane than validation, but in real products they often meet in the same field.
- The interactive examples below use mocked city data so the playground behaves like a real lookup flow without depending on an unavailable demo API