Migration to v4

A comprehensive guide to migrate your application from Nuxt UI v3 to Nuxt UI v4.

Nuxt UI v4.0 represents a major milestone where Nuxt UI Pro has been merged into the main Nuxt UI package. This means all Pro components and features are now available in the open-source @nuxt/ui package.

Nuxt UI v4 requires Nuxt 4 due to some dependencies. Make sure to upgrade to Nuxt 4 before migrating to Nuxt UI v4.

This guide provides step-by-step instructions to migrate your application from v3 to v4.

Migrate your project

Update dependencies

Replace Nuxt UI Pro with Nuxt UI:

If you were using @nuxt/ui-pro, replace it with @nuxt/ui:

pnpm remove @nuxt/ui-pro
pnpm add @nuxt/ui@latest

If you were already using @nuxt/ui v3, simply update to v4:

pnpm add @nuxt/ui@latest

Update configuration

Replace @nuxt/ui-pro with @nuxt/ui in your modules:

nuxt.config.ts
export default defineNuxtConfig({
  modules: [
-   '@nuxt/ui-pro',
+   '@nuxt/ui'
  ]
})

Update the import in your vite.config.ts:

vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
- import uiPro from '@nuxt/ui-pro/vite'
+ import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
-   uiPro({
+   ui({
      ui: {
        colors: {
          primary: 'green',
          neutral: 'slate'
        }
      }
    })
  ]
})

Move component theming configuration:

If you had custom component theming in the uiPro key, move it to the ui key:

vite.config.ts
export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        colors: {
          primary: 'green',
          neutral: 'slate'
        },
-     },
-     uiPro: {
-       pageCard: {
-         slots: {
-           root: 'rounded-xl',
-         }
-       }
+       pageCard: {
+         slots: {
+           root: 'rounded-xl',
+         }
+       }
      }
    })
  ]
})

Update your CSS imports:

If you were importing @nuxt/ui-pro styles, replace with @nuxt/ui:

app/assets/css/main.css
@import "tailwindcss";
- @import "@nuxt/ui-pro";
+ @import "@nuxt/ui";

Update CSS imports:

Update your CSS file:

src/assets/css/main.css
@import "tailwindcss";
- @import "@nuxt/ui-pro";
+ @import "@nuxt/ui";

Changes from v3

Now that you have updated your project dependencies, you need to address the breaking changes in Nuxt UI v4.

Merged Pro components

All Nuxt UI Pro components are now available in the main @nuxt/ui package. You can continue using them exactly as before, but they're now imported from @nuxt/ui instead of @nuxt/ui-pro.

- import { PageHero, PageSection } from '@nuxt/ui-pro'
+ import type { BannerProps } from '@nuxt/ui'

Renamed components

Several components have been renamed for better consistency:

v3v4
ButtonGroupFieldGroup
PageMarqueeMarquee

Removed components

Some components have been removed in favor of more standard alternatives:

v3v4
PageAccordionAccordion
<template>
- <UPageAccordion :items="faqItems" />
+ <UAccordion :items="items" :unmount-on-hide="false" :ui="{ trigger: 'text-base', body: 'text-base text-muted' }" />
</template>

AI SDK v5 migration (Optional)

This section only applies if you're using the AI SDK and chat components (ChatMessage, ChatMessages, ChatPrompt, ChatPromptSubmit, ChatPalette). If you're not using AI features, you can skip this section.

First, update your ai dependency:

// package.json
{
  "dependencies": {
-   "ai": "^4.x.x"
+   "ai": "^5.x.x"
  }
}

Chat components have been updated to work with AI SDK v5 too. The main changes are:

useChatChat class

The useChat composable has been replaced with the new Chat class:

<script setup lang="ts">
- import { useChat } from '@ai-sdk/vue'
+ import { Chat } from '@ai-sdk/vue'
+ import type { UIMessage } from 'ai'

- const { messages, input, handleSubmit, status, error, reload, setMessages } = useChat()
+ const messages: UIMessage[] = []
+ const input = ref('')
+ 
+ const chat = new Chat({
+   messages
+ })
+ 
+ function handleSubmit(e: Event) {
+   e.preventDefault()
+   chat.sendMessage({ text: input.value })
+   input.value = ''
+ }
</script>

Message format: contentparts

Messages now use the parts format instead of content:

// When manually creating messages
- setMessages([{
+ messages.push({
  id: '1',
  role: 'user',
- content: 'Hello world'
+ parts: [{ type: 'text', text: 'Hello world' }]
- }])
+ })

// In templates
<template>
- <UChatMessage :content="message.content" />
+ <UChatMessage :parts="message.parts" />
</template>

Method changes

Some methods have been renamed:

// Regenerate the last message
- reload()
+ chat.regenerate()

// Access chat state
- :messages="messages"
- :status="status"
+ :messages="chat.messages"
+ :status="chat.status"

New getTextFromMessage utility

Nuxt UI provides a new utility to extract text from AI SDK v5 message parts:

<script setup lang="ts">
import { getTextFromMessage } from '@nuxt/ui/utils/ai'
</script>

<template>
  <UChatMessages :messages="chat.messages" :status="chat.status">
    <template #content="{ message }">
      <!-- Extract text from message parts and render with MDC -->
      <MDC :value="getTextFromMessage(message)" :cache-key="message.id" unwrap="p" />
    </template>
  </UChatMessages>
</template>

This utility safely extracts text content from the parts array of AI SDK v5 messages.

For more details on AI SDK v5 changes, review the official AI SDK v5 migration guide.

Check out the full difference for the AI SDK v4 to v5 migration in the upgrade PR!
Check out the AI Chat template for a complete implementation example.