---
title: "Migrating from 0.0.x"
description: "What changed in the rewrite and how to update."
canonical_url: "https://nuxt-formisch.onmax.me/getting-started/migration"
---
# Migrating from 0.0.x

> What changed in the rewrite and how to update.

The module was rewritten on top of Formisch 1 and Nuxt 4. Most apps need a handful of renames.

## Requirements

- Nuxt 4 only.
- Forms are Valibot-only. The module no longer looks for Zod or ArkType. `readValidatedFormBody` on the server still takes any [Standard Schema](https://standardschema.dev).
- You no longer need `@formisch/vue` in your own `package.json`.

## Server

`useFormValidation` is now `readValidatedFormBody`. Issue paths in `data.issues` are plain keys and indexes: `['members', 0, 'name']`. See [Server validation](https://nuxt-formisch.onmax.me/forms/server-validation).

```diff [server/api/login.post.ts]
- const data = await useFormValidation(event, LoginSchema)
+ const data = await readValidatedFormBody(event, LoginSchema)
```

## Composables and methods

`useFormFields` and `useNuxtUIField` are removed. `useField` takes the form and config directly now, and Nuxt UI inputs bind to the field store:

```diff
- const { field } = useFormFields(form)
- const email = useNuxtUIField(field('email'))
+ const email = useField(form, { path: ['email'] })
```

```diff
- <UFormField label="Email" :error="email.error">
-   <UInput v-model="email.modelValue" />
+ <UFormField label="Email" :error="email.errors?.[0]">
+   <UInput v-model="email.input" />
```

`getAllErrors` is gone in Formisch 1. Use `getDeepErrors(form)`.

## FAutoForm

<table>
<thead>
  <tr>
    <th>
      Before
    </th>
    
    <th>
      After
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        :initial-values
      </code>
    </td>
    
    <td>
      <code>
        :initial-input
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        @submit="(data) => …"
      </code>
    </td>
    
    <td>
      <code>
        @submit="(output, event) => …"
      </code>
      
      . <code>
        output
      </code>
      
       is typed from the schema, and an async handler is awaited.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        @error
      </code>
    </td>
    
    <td>
      Removed. Errors show on the fields; read them from the exposed <code>
        form
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      No default button
    </td>
    
    <td>
      A submit button renders unless you fill the <code>
        actions
      </code>
      
       slot.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        #actions="{ isDirty, isSubmitting, reset }"
      </code>
    </td>
    
    <td>
      <code>
        #actions="{ form, reset }"
      </code>
      
      : use <code>
        form.isDirty
      </code>
      
      , <code>
        form.isSubmitting
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        #field:email="{ field, store }"
      </code>
    </td>
    
    <td>
      <code>
        #[`field:email`]="{ field, path, form }"
      </code>
      
      , keyed by dotted path.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        #section:<name>
      </code>
    </td>
    
    <td>
      Removed. Use <code>
        section
      </code>
      
       for headings and <code>
        field:
      </code>
      
       slots for custom markup.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fieldConfig
      </code>
      
       keyed by top-level name
    </td>
    
    <td>
      Keyed by dotted path without array indexes: <code>
        'address.city'
      </code>
      
      , <code>
        'members.name'
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        v.metadata({ fieldType: 'json' })
      </code>
    </td>
    
    <td>
      <code>
        v.metadata({ type: 'json' })
      </code>
    </td>
  </tr>
</tbody>
</table>

`FAutoFormField`, `FAutoFormObject` and `FAutoFormArray` are no longer registered.

## Theme

AutoForm theming moved from `appConfig.ui.autoForm*` to one set of slots under `appConfig.formisch.autoForm.slots`. See [Theming](https://nuxt-formisch.onmax.me/auto-form/theming) for the new slot names.

```diff [app/app.config.ts]
export default defineAppConfig({
-   ui: {
-     autoForm: { root: 'space-y-8' },
-     autoFormArray: { item: 'bg-muted' },
-   },
+   formisch: {
+     autoForm: { slots: { root: 'space-y-8', arrayItem: 'bg-muted' } },
+   },
  })
```

## introspectSchema

`ResolvedField` changed shape: UI options sit on the field itself (`field.label`, not `field.ui.label`), nested fields are in `fields` (was `children`), array items in `item` (was `itemSchema`), picklists and enums are `type: 'enum'` (was `'picklist'`), and records are `type: 'json'`. Every field has a dotted `key`.


## Sitemap

See the full [sitemap](https://nuxt-formisch.onmax.me/sitemap.md) for all pages.
