# Nuxt UI

> Build UIs with @nuxt/ui v4 — 125+ accessible Vue components with Tailwind CSS theming. Use when creating interfaces, customizing themes to match a brand, building forms, or composing layouts like dashboards, docs sites, and chat interfaces.

- Skill: `alexanderop/nuxt-ui` (Agent Skill, multi-file: 9 files)
- Install (CLI): `npx skillmds@latest add alexanderop/nuxt-ui`
- Raw SKILL.md: https://api.skillmd.com/api/skills/alexanderop/nuxt-ui/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: alexanderop (https://skillmd.com/u/alexanderop)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/alexanderop/nuxt-ui

---


# Nuxt UI

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).

## Installation

### Nuxt

```bash
pnpm add @nuxt/ui tailwindcss
```

```ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ["@nuxt/ui"],
  css: ["~/assets/css/main.css"],
});
```

```css
/* app/assets/css/main.css */
@import "tailwindcss";
@import "@nuxt/ui";
```

```vue
<!-- app.vue -->
<template>
  <UApp>
    <NuxtPage />
  </UApp>
</template>
```

### Vue (Vite)

```bash
pnpm add @nuxt/ui tailwindcss
```

```ts
// 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()],
});
```

```ts
// 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");
```

```css
/* assets/main.css */
@import "tailwindcss";
@import "@nuxt/ui";
```

```vue
<!-- src/App.vue -->
<template>
  <UApp>
    <RouterView />
  </UApp>
</template>
```

> **Vue**: Add `class="isolate"` to your root `<div id="app">` in `index.html`.

> **Vue + Inertia**: Use `ui({ router: 'inertia' })` in `vite.config.ts`.

### UApp

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](references/composables.md)).

## Icons

Nuxt UI uses [Iconify](https://iconify.design/) for 200,000+ icons. In Nuxt, `@nuxt/icon` is auto-registered. In Vue, icons work out of the box via the Vite plugin.

### Naming convention

Icons use the format `i-{collection}-{name}`:

```vue
<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](https://icones.js.org). The `lucide` collection is used throughout Nuxt UI defaults.

### Install icon collections locally

```bash
pnpm i @iconify-json/lucide
pnpm i @iconify-json/simple-icons
```

### Custom local collections (Nuxt)

```ts
// nuxt.config.ts
export default defineNuxtConfig({
  icon: {
    customCollections: [
      {
        prefix: "custom",
        dir: "./app/assets/icons",
      },
    ],
  },
});
```

```vue
<UIcon name="i-custom-my-icon" />
```

## Theming & Branding

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](references/theming.md) for the full list.

### Colors

7 semantic colors (`primary`, `secondary`, `success`, `info`, `warning`, `error`, `neutral`) configurable at runtime:

```ts
// Nuxt — app.config.ts
export default defineAppConfig({
  ui: { colors: { primary: "indigo", neutral: "zinc" } },
});
```

```ts
// 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" } },
    }),
  ],
});
```

### Customizing components

**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:

```vue
<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**: `.nuxt/ui/<component>.ts`
- **Vue**: `node_modules/.nuxt-ui/ui/<component>.ts`

> For CSS variables, custom colors, global config, compound variants, and a **full brand customization playbook**, see [references/theming.md](references/theming.md)

## Composables

```ts
// 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](references/composables.md)

## Form validation

Uses Standard Schema — works with Zod, Valibot, Yup, or Joi.

```vue
<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](references/components.md#form)

## Overlays

```vue
<!-- 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](references/components.md#overlay)

## Layouts

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](references/layouts/page.md)           |
| Dashboard | Admin UI with resizable sidebar and panels              | [layouts/dashboard.md](references/layouts/dashboard.md) |
| Docs      | Documentation with sidebar nav and TOC                  | [layouts/docs.md](references/layouts/docs.md)           |
| Chat      | AI chat with messages and prompt                        | [layouts/chat.md](references/layouts/chat.md)           |
| Editor    | Rich text editor with toolbars                          | [layouts/editor.md](references/layouts/editor.md)       |

## Templates

Official starter templates at [github.com/nuxt-ui-templates](https://github.com/nuxt-ui-templates):

| Template  | Framework | GitHub                                                                                    |
| --------- | --------- | ----------------------------------------------------------------------------------------- |
| Starter   | Nuxt      | [nuxt-ui-templates/starter](https://github.com/nuxt-ui-templates/starter)                 |
| Starter   | Vue       | [nuxt-ui-templates/starter-vue](https://github.com/nuxt-ui-templates/starter-vue)         |
| Dashboard | Nuxt      | [nuxt-ui-templates/dashboard](https://github.com/nuxt-ui-templates/dashboard)             |
| Dashboard | Vue       | [nuxt-ui-templates/dashboard-vue](https://github.com/nuxt-ui-templates/dashboard-vue)     |
| SaaS      | Nuxt      | [nuxt-ui-templates/saas](https://github.com/nuxt-ui-templates/saas)                       |
| Landing   | Nuxt      | [nuxt-ui-templates/landing](https://github.com/nuxt-ui-templates/landing)                 |
| Docs      | Nuxt      | [nuxt-ui-templates/docs](https://github.com/nuxt-ui-templates/docs)                       |
| Portfolio | Nuxt      | [nuxt-ui-templates/portfolio](https://github.com/nuxt-ui-templates/portfolio)             |
| Chat      | Nuxt      | [nuxt-ui-templates/chat](https://github.com/nuxt-ui-templates/chat)                       |
| Editor    | Nuxt      | [nuxt-ui-templates/editor](https://github.com/nuxt-ui-templates/editor)                   |
| Changelog | Nuxt      | [nuxt-ui-templates/changelog](https://github.com/nuxt-ui-templates/changelog)             |
| Starter   | Laravel   | [nuxt-ui-templates/starter-laravel](https://github.com/nuxt-ui-templates/starter-laravel) |
| Starter   | AdonisJS  | [nuxt-ui-templates/starter-adonis](https://github.com/nuxt-ui-templates/starter-adonis)   |

> When starting a new project, clone the matching template instead of setting up from scratch.

## Additional references

Load based on your task — **do not load all at once**:

- [references/theming.md](references/theming.md) — CSS variables, custom colors, component theme overrides
- [references/components.md](references/components.md) — all 125+ components by category with props and usage
- [references/composables.md](references/composables.md) — useToast, useOverlay, defineShortcuts
- Generated theme files — all slots, variants, and default classes for any component (Nuxt: `.nuxt/ui/<component>.ts`, Vue: `node_modules/.nuxt-ui/ui/<component>.ts`)

