Migration to v4
Nuxt UI v4 marks a major milestone: Nuxt UI and Nuxt UI Pro are now unified into a single, fully open-source and free library. You now have access to 100+ production-ready components, all available in the @nuxt/ui package.
This guide provides step-by-step instructions to migrate your application from v3 to v4.
Migrate your project
From Nuxt UI Pro
- Replace
@nuxt/ui-prowith@nuxt/uiin yourpackage.json:
pnpm remove @nuxt/ui-pro
pnpm add @nuxt/ui@alpha
yarn remove @nuxt/ui-pro
yarn add @nuxt/ui@alpha
npm uninstall @nuxt/ui-pro
npm install @nuxt/ui@alpha
bun remove @nuxt/ui-pro
bun add @nuxt/ui@alpha
- Replace
@nuxt/ui-prowith@nuxt/uiin yournuxt.config.ts:
export default defineNuxtConfig({
modules: [
- '@nuxt/ui-pro',
+ '@nuxt/ui'
]
})
- Replace
@nuxt/ui-prowith@nuxt/uiin yourvite.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'
}
}
})
]
})
- Use the
uikey instead ofuiProin yourapp.config.ts:
export default defineAppConfig({
ui: {
colors: {
primary: 'green',
neutral: 'slate'
},
+ pageCard: {
+ slots: {
+ root: 'rounded-xl',
+ }
+ }
},
- uiPro: {
- pageCard: {
- slots: {
- root: 'rounded-xl',
- }
- }
- }
})
- Use the
uikey instead ofuiProin yourvite.config.ts:
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
colors: {
primary: 'green',
neutral: 'slate'
},
+ pageCard: {
+ slots: {
+ root: 'rounded-xl',
+ }
+ }
},
- uiPro: {
- pageCard: {
- slots: {
- root: 'rounded-xl',
- }
- }
- }
})
]
})
- Replace
@nuxt/ui-prowith@nuxt/uiin your CSS:
@import "tailwindcss";
- @import "@nuxt/ui-pro";
+ @import "@nuxt/ui";
@import "tailwindcss";
- @import "@nuxt/ui-pro";
+ @import "@nuxt/ui";
From Nuxt UI
- When upgrading from Nuxt UI v3, you simply need to update to v4:
pnpm add @nuxt/ui@alpha
yarn add @nuxt/ui@alpha
npm install @nuxt/ui@alpha
bun add @nuxt/ui@alpha
Changes from v3
After upgrading to Nuxt UI v4, please note the following important changes:
Merged components
Nuxt UI Pro components have been integrated into the main @nuxt/ui package. You can keep using them as before, but you now need to import from @nuxt/ui instead of @nuxt/ui-pro:
- import type { BannerProps } from '@nuxt/ui-pro'
+ import type { BannerProps } from '@nuxt/ui'
Renamed components
Several components have been renamed for better consistency:
ButtonGrouphas been replaced withFieldGroup:
<template>
- <UButtonGroup>
+ <UFieldGroup>
<UButton label="Button" />
<UButton icon="i-lucide-chevron-down" />
- </UButtonGroup>
+ </UFieldGroup>
</template>
PageMarqueehas been replaced withMarquee:
<template>
- <UPageMarquee :items="items" />
+ <UMarquee :items="items" />
</template>
Removed components
Some components have been removed in favor of more standard alternatives:
PageAccordionhas been replaced withAccordion:
<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.
- Update
@ai-sdk/vueandaidependencies in yourpackage.json:
{
"dependencies": {
- "@ai-sdk/vue": "^1.2.x",
+ "@ai-sdk/vue": "^2.0.x",
- "ai": "^4.3.x"
+ "ai": "^5.0.x"
}
}
useChatcomposable has been replaced with the newChatclass:
<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>
- Messages now use
partsinstead ofcontent:
// 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>
- 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
getTextFromMessageutility 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>