Help us improve
Share bugs, ideas, or general feedback.
From nuxt-ui
Build accessible UIs with Nuxt UI v4: 125+ Vue components using Tailwind CSS and Tailwind Variants. Supports Nuxt, Vue Vite, Laravel Inertia, AdonisJS Inertia for interfaces, themes, forms, dashboards, docs sites, chat apps.
npx claudepluginhub pleaseai/claude-code-plugins --plugin nuxt-uiHow this skill is triggered — by the user, by Claude, or both
Slash command
/nuxt-ui:nuxt-uiThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Vue component library built on [Reka UI](https://reka-ui.com/) + [Tailwind CSS](https://tailwindcss.com/) + [Tailwind Variants](https://www.tailwind-variants.org/). Works with Nuxt, Vue (Vite), Laravel (Inertia), and AdonisJS (Inertia).
Build styled UIs with @nuxt/ui v4 components including forms with Zod/Valibot validation, data tables with sorting, and modals/overlays. Also covers Tailwind Variants theming.
Provides Nuxt UI v4 components for Nuxt 4 apps: 125+ accessible Tailwind v4 elements with Reka UI, dark mode, theming. Use for dashboards, forms, overlays, layouts, or component/theming/TS errors.
Sets up production-ready shadcn-vue UI components in Vue/Nuxt apps with Tailwind CSS and Reka UI. Use for accessible forms, data tables, charts, dark mode, and component imports.
Share bugs, ideas, or general feedback.
Vue component library built on Reka UI + Tailwind CSS + Tailwind Variants. Works with Nuxt, Vue (Vite), Laravel (Inertia), and AdonisJS (Inertia).
pnpm add @nuxt/ui tailwindcss
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/ui'],
css: ['~/assets/css/main.css']
})
/* app/assets/css/main.css */
@import "tailwindcss";
@import "@nuxt/ui";
<!-- app.vue -->
<template>
<UApp>
<NuxtPage />
</UApp>
</template>
pnpm add @nuxt/ui tailwindcss
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui()
]
})
// src/main.ts
import './assets/main.css'
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import ui from '@nuxt/ui/vue-plugin'
import App from './App.vue'
const app = createApp(App)
const router = createRouter({
routes: [],
history: createWebHistory()
})
app.use(router)
app.use(ui)
app.mount('#app')
/* assets/main.css */
@import "tailwindcss";
@import "@nuxt/ui";
<!-- src/App.vue -->
<template>
<UApp>
<RouterView />
</UApp>
</template>
Vue: Add
class="isolate"to your root<div id="app">inindex.html.
Vue + Inertia: Use
ui({ router: 'inertia' })invite.config.ts.
Wrapping your app in UApp is required — it provides global config for toasts, tooltips, and programmatic overlays. It also accepts a locale prop for i18n (see composables reference).
Nuxt UI uses Iconify for 200,000+ icons. In Nuxt, @nuxt/icon is auto-registered. In Vue, icons work out of the box via the Vite plugin.
Icons use the format i-{collection}-{name}:
<UIcon name="i-lucide-sun" class="size-5" />
<UButton icon="i-lucide-plus" label="Add" />
<UAlert icon="i-lucide-info" title="Heads up" />
Browse all icons at icones.js.org. The
lucidecollection is used throughout Nuxt UI defaults.
pnpm i @iconify-json/lucide
pnpm i @iconify-json/simple-icons
// nuxt.config.ts
export default defineNuxtConfig({
icon: {
customCollections: [{
prefix: 'custom',
dir: './app/assets/icons'
}]
}
})
<UIcon name="i-custom-my-icon" />
Nuxt UI ships with a default look. The goal is to adapt it to your brand so every app looks unique.
Always use semantic utilities (text-default, bg-elevated, border-muted), never raw Tailwind palette colors. See references/theming.md for the full list.
7 semantic colors (primary, secondary, success, info, warning, error, neutral) configurable at runtime:
// Nuxt — app.config.ts
export default defineAppConfig({
ui: { colors: { primary: 'indigo', neutral: 'zinc' } }
})
// Vue — vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: { colors: { primary: 'indigo', neutral: 'zinc' } }
})
]
})
Override priority (highest wins): ui prop / class prop > global config > theme defaults.
The ui prop overrides a component's slots after variants are computed — it wins over everything:
<UButton :ui="{ base: 'rounded-none', trailingIcon: 'size-3 rotate-90' }" />
<UCard :ui="{ header: 'bg-muted', body: 'p-8' }" />
Read the generated theme file to find slot names for any component:
.nuxt/ui/<component>.tsnode_modules/.nuxt-ui/ui/<component>.tsFor CSS variables, custom colors, global config, compound variants, and a full brand customization playbook, see references/theming.md
// Notifications
const toast = useToast()
toast.add({ title: 'Saved', color: 'success', icon: 'i-lucide-check' })
// Programmatic overlays
const overlay = useOverlay()
const modal = overlay.create(MyModal)
const { result } = modal.open({ title: 'Confirm' })
await result
// Keyboard shortcuts
defineShortcuts({
meta_k: () => openSearch(),
escape: () => close()
})
For full composable reference, see references/composables.md
Uses Standard Schema — works with Zod, Valibot, Yup, or Joi.
<script setup lang="ts">
import { z } from 'zod'
const schema = z.object({
email: z.string().email('Invalid email'),
password: z.string().min(8, 'Min 8 characters')
})
type Schema = z.output<typeof schema>
const state = reactive<Partial<Schema>>({ email: '', password: '' })
function onSubmit() {
// UForm validates before emitting @submit — state is valid here
}
</script>
<template>
<UForm :schema="schema" :state="state" @submit="onSubmit">
<UFormField name="email" label="Email" required>
<UInput v-model="state.email" type="email" />
</UFormField>
<UFormField name="password" label="Password" required>
<UInput v-model="state.password" type="password" />
</UFormField>
<UButton type="submit">Sign in</UButton>
</UForm>
</template>
For all form components and validation patterns, see references/components.md
<!-- Modal -->
<UModal v-model:open="isOpen" title="Edit" description="Edit your profile">
<template #body>Content</template>
<template #footer>
<UButton variant="ghost" @click="isOpen = false">Cancel</UButton>
<UButton @click="save">Save</UButton>
</template>
</UModal>
<!-- Slideover (side panel) -->
<USlideover v-model:open="isOpen" title="Settings" side="right">
<template #body>Content</template>
</USlideover>
<!-- Dropdown menu (flat array) -->
<UDropdownMenu :items="[
{ label: 'Edit', icon: 'i-lucide-pencil' },
{ type: 'separator' },
{ label: 'Delete', icon: 'i-lucide-trash', color: 'error' }
]">
<UButton icon="i-lucide-ellipsis-vertical" variant="ghost" />
</UDropdownMenu>
<!-- Dropdown menu (nested array — groups with automatic separators) -->
<UDropdownMenu :items="[
[{ label: 'Edit', icon: 'i-lucide-pencil' }, { label: 'Duplicate', icon: 'i-lucide-copy' }],
[{ label: 'Delete', icon: 'i-lucide-trash', color: 'error' }]
]">
<UButton icon="i-lucide-ellipsis-vertical" variant="ghost" />
</UDropdownMenu>
For all overlay components, see references/components.md
Nuxt UI provides components to compose full page layouts. Load the reference matching your use case:
| Layout | Description | Reference |
|---|---|---|
| Page | Landing, blog, changelog, pricing — public-facing pages | layouts/page.md |
| Dashboard | Admin UI with resizable sidebar and panels | layouts/dashboard.md |
| Docs | Documentation with sidebar nav and TOC | layouts/docs.md |
| Chat | AI chat with messages and prompt | layouts/chat.md |
| Editor | Rich text editor with toolbars | layouts/editor.md |
Official starter templates at github.com/nuxt-ui-templates:
| Template | Framework | GitHub |
|---|---|---|
| Starter | Nuxt | nuxt-ui-templates/starter |
| Starter | Vue | nuxt-ui-templates/starter-vue |
| Dashboard | Nuxt | nuxt-ui-templates/dashboard |
| Dashboard | Vue | nuxt-ui-templates/dashboard-vue |
| SaaS | Nuxt | nuxt-ui-templates/saas |
| Landing | Nuxt | nuxt-ui-templates/landing |
| Docs | Nuxt | nuxt-ui-templates/docs |
| Portfolio | Nuxt | nuxt-ui-templates/portfolio |
| Chat | Nuxt | nuxt-ui-templates/chat |
| Editor | Nuxt | nuxt-ui-templates/editor |
| Changelog | Nuxt | nuxt-ui-templates/changelog |
| Starter | Laravel | nuxt-ui-templates/starter-laravel |
| Starter | AdonisJS | nuxt-ui-templates/starter-adonis |
When starting a new project, clone the matching template instead of setting up from scratch.
Load based on your task — do not load all at once:
.nuxt/ui/<component>.ts, Vue: node_modules/.nuxt-ui/ui/<component>.ts)