Known Limitations
Most of these fail silently - no error, no warning, just a missing label or a validation message that never appears - so they're worth reading once.
Setup
- Inputs are not auto-registered. The module only adds a plugin, the composables, and
FUDataView/FUDataEdit/FUDataDebug/FUAutoForm. ThenuxtUI*input and output types exist only once yourformkit.config.tsregisters them viacreateNuxtUiFormkitConfig(), and that file is only picked up if@formkit/nuxtis in yourmodules. - Multi-step needs its plugin.
nuxtUIMultiStep/nuxtUIStepdo nothing unless you callcreateNuxtUiFormkitConfig({ multiStep: true })(or registercreateMultiStepPlugin()yourself). In development anuxtUIMultiStepwithout the plugin logs a console warning saying so. See Multi-Step. - Don't override
pluginsafter spreading the helper.defaultConfig({ ...createNuxtUiFormkitConfig(), plugins: [x] })replaces the whole array and silently drops the asterisk plugin (required fields lose their*). Pass yours ascreateNuxtUiFormkitConfig({ plugins: [x] }), which appends them. - Schemas can only use globally registered Nuxt UI components. The module registers
UButton,UIcon,UTabs,UUserandUTooltip. Any other$cmp: 'UXxx'in a schema renders as an unstyled custom element. - Server rendering has a few things that only appear after hydration. The editor is built in the browser (the content below it moves down by about 73px when it mounts), a multi-step's tab strip appears after hydration, and a date field without an explicit
timeZoneshows the server's day until the page mounts. None of this is a hydration mismatch. See Server-Side Rendering.
Validation timing
FormKit reveals validation messages on blur by default, and Nuxt UI components don't all emit one.
nuxtUIColorPickeris pointer-only. Nothing insideUColorPickeris focusable, so "blur" means releasing the pointer after picking a color; keyboard users can't operate it at all.nuxtUISelectreveals on dropdown close only. Tabbing through without opening it shows nothing. Use'live', ornuxtUISelectMenu, which has no such gap. See Selection Components.requiredpasses for a booleanfalse. OnnuxtUICheckbox/nuxtUISwitch, use theacceptedrule instead.
Forms and composables
useFormKitForm(id)is keyed on the form'sid, not itsname, and the form must be mounted in the DOM.submit()can't report when FormKit's own submission finishes;isLoadingonly wraps thehandleryou pass.hasErrorsis not!isValid.hasErrorscounts only error messages (e.g. fromsetErrors); a form with failed validation rules reportshasErrors: false. UseisValidfor rule failures.isDirtyis sticky by default - it staystrueafter a field is edited back to its original value. Setdirty-behavior="compare"(FUDataEdithas adirtyBehaviorprop) to track the live difference.- Overlays aren't concurrent.
useFormKitOverlay().edit()/auto()share one overlay instance; a second call before the first resolves takes it over. See One Overlay Instance at a Time. - Autosave attaches at form creation only. It needs a stable form
name, covers the root form (not nested groups), and can't be added later fromuseFormKitForm. SeecreateAutosavePlugin.
Repeaters and schemas
node.at('items.0.email')can't reach intonuxtUIRepeater. The repeater's outer and inner nodes share a name, so FormKit's address lookup fails silently. The Standard Schema bridge works around this; your own code addressing repeater rows has to as well.- Inside repeater rows, read sibling values with
$node.value.<field>.$get(name)resolves byid, not byname. - The schema expression language has no unary
!.if: '!$value'is silently ignored; compare explicitly instead.
Inputs
- Date inputs emit
@internationalized/dateobjects by default (CalendarDateetc.), which aren't JSON-serializable. SetvalueType: 'date'or'iso'for plain values - seenuxtUIInputDate. coloris overridden while a field is invalid - the wrapped component is switched to itserrorcolor.- FormKit's own label/help/messages chrome always surrounds the Nuxt UI component, so you won't get Nuxt UI's
UFormFieldlayout. @formkit/addonsplugins that assume native FormKit types silently no-op.createMaxLengthCountdownPluginandcreateFloatingLabelsPlugindon't work withnuxtUI*types.
FUAutoForm
- Fields it can't map are dropped, not errored.
null,undefined, functions and other non-plain values never become inputs; with Zod, only string, number, boolean, date, array and object schemas map - enums, unions and literals are skipped. - Schema introspection is by duck-typing, tested against Valibot 1.x and Zod 4. Zod 3 isn't supported, and other Standard Schema libraries (e.g. ArkType) get no inference - they work for validation, not for building the form.
Localization
Built-in labels are English-only unless noted: "Save"/"Cancel"/"Reset" on FUDataEdit and the overlays, "Keep editing"/"Discard" in the confirmDiscard prompt, "Yes"/"No" on FUOutputBoolean, and "Add Item" on the repeater. Multi-step's Previous/Next resolve through FormKit's $ui.prev/$ui.next i18n keys. Most of these can be overridden through props.
Not implemented
UStepper as a multi-step display mode (tabs only), FUOutputAvatar, and FUOutputProgressGroup.