Reference
Architecture
useForm
│
├── Schema normalisation (json / zod / yup / valibot / openapi)
│ └── FieldDefinition[]
│
├── ConditionEvaluator
│ watchEffect → resolves visible / disabled / options per field
│
├── ValidationEngine
│ sync validators → errors Record<path, string[]>
│ async validators → debounced 300ms
│ getByPath / setByPath — dot-path helpers, also exported standalone
│
├── schemaUtils
│ mergeSchemas / omitFields / pickFields / extendField
│ discriminatedFields — visible wiring for discriminator-driven field sets
│
├── serverErrors
│ applyServerErrors / normalizeServerErrors — laravel / drf / flat / custom
│
├── registry
│ createFormRegistry (Vue plugin) / provideRegistry (subtree) / useRegistry
│ — component-swap chain read by FormRenderer and its theme variants
│
├── MaskEngine (standalone)
│ applyMask / removeMask / bindMask
│
└── (optional) UI subpackages
FormRenderer [/ui]
TailwindFormRenderer [/ui/tailwind]
ShadcnFormRenderer [/ui/shadcn]
PrimeVueFormRenderer [/ui/primevue]
NaiveFormRenderer [/ui/naive]
useFieldArray [core]
useMultiStepForm [core]
useFormDebug [core]
useFormField [core]
installFormDevtools [/devtools]SSR compatibility
The core (useForm, validators, parsers, ConditionEvaluator) does not use browser APIs. bindMask and FormRenderer use DOM APIs — wrap them in onMounted or <ClientOnly> when needed. Persisted forms (persist: 'local' | 'session') guard the storage read with typeof window !== 'undefined', so they resolve to the field's own defaultValue during SSR and pick up the real stored value after mount.
Accessibility
All built-in field components include full a11y attributes:
aria-required
Set to "true" on required inputs, selects, textareas, fieldsets.
aria-invalid
Set to "true" when the field is touched and has errors.
aria-describedby
Points to "{name}-error" when errors are present.
role="alert" + aria-live="polite"
Error lists are announced by screen readers on appearance.
label[for] + input[id]
All inputs have matching label and id.
fieldset + legend
Radio groups use semantic grouping.
aria-checked
Checkboxes reflect boolean state explicitly.
Bundle size & peer dependencies
| Entry point | Peer deps | Notes |
|---|---|---|
vue-form-schema | vue ^3.3 | Core — headless, no UI |
vue-form-schema/zod | zod ^3 | Optional adapter |
vue-form-schema/yup | yup ^1 | Optional adapter |
vue-form-schema/valibot | valibot ^1 | Optional adapter |
vue-form-schema/openapi | none | Standard JSON Schema / OpenAPI adapter — no peer deps |
vue-form-schema/ui | vue ^3.3 | BEM-styled built-in components |
vue-form-schema/ui/tailwind | vue ^3.3, Tailwind CSS | Tailwind utility-class components |
vue-form-schema/ui/shadcn | vue ^3.3, Tailwind CSS | shadcn/ui-styled Tailwind markup (see note above — not a shadcn-vue component wrapper) |
vue-form-schema/ui/primevue | vue ^3.3, primevue ^4 | ^5 | Real PrimeVue component wrappers |
vue-form-schema/ui/naive | vue ^3.3, naive-ui ^2.38 | Real Naive UI component wrappers |
vue-form-schema/devtools | @vue/devtools-api ^6 | ^7 | ^8 | Vue DevTools inspector + timeline, dev-only |
vue-form-schema/style.css | — | Stylesheet for the ui/primevue theme's file-upload dropzone — import it once if you use that theme's FileField |
All entry points are tree-shakeable ESM + CJS dual builds.
License
MIT