4️⃣

Nuxt UI v4 がついにリリース!無料で使える強力コンポーネントライブラリ

に公開

はじめに

2025年9月29日、Nuxt UI v4が正式リリースされました。
今回の大きなニュースは、これまで有料だった Nuxt UI Pro が完全無料で利用できるようになったことです。Vue/Nuxt開発者にとって、UIコンポーネントの選択肢が大幅に広がります。
https://nuxt.com/blog/nuxt-ui-v4

公式ドキュメントや関連記事を調べて、Nuxt UI v4の概要と主要コンポーネントの使い方を紹介していきたいと思います。

Nuxt UI v4とは?

Nuxt UI v4は、Vue/Nuxt用のオープンソースUIライブラリです。

主な特徴:
110以上のコンポーネント:ボタン、フォーム、テーブル、モーダルなど、Webアプリ開発に必要なほぼすべてをカバー。
12種類のテンプレート:Landingページ、SaaS、Dashboard、Docsサイト、Chatアプリ、Portfolio、Changelogなど。
Figmaキット:2,000以上のコンポーネントバリエーションとデザイントークンが提供。
Vue/Nuxt互換:AdonisやLaravelとも統合可能。
AI支援:MCPサーバーやLLMs.txtを使って、生成AIでコンポーネント提案・実装をサポート。

以前は Pro コンポーネントは有料でしたが、今では完全に無料で利用可能です。

Nuxt UI v4を使ってみる

1. Nuxtプロジェクトにインストール

新規プロジェクトの場合:

bash
npm create nuxt@latest -- -t ui

既存プロジェクトの場合:

bash
npm install @nuxt/ui

2. nuxt.config.tsにモジュールを追加

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

3. Tailwind CSSとNuxt UIをインポート

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

4. nuxt.config.tsにcssを追加

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/ui']
+ css: ['~/assets/css/main.css']
})

5. アプリをラップ

app.vue
<template>
  <UApp>
    <NuxtPage />
  </UApp>
</template>

4. ローカル環境を起動

bash
npm run dev

主要コンポーネント

1. ボタン(UButton)

Nuxt UI v4では、uiプロパティを使うことで、自分好みのスタイルに細かくカスタマイズできます。

index.vue
<template>
  <!-- UButtonコンポーネント: ボタンの色やアイコンを設定 -->
  <UButton
    icon="i-lucide-rocket"    <!-- 左側にロケットアイコン -->
    color="neutral"            <!-- カラーバリエーション -->
    variant="outline"          <!-- 枠線のみのスタイル -->
    :ui="{ leadingIcon: 'text-primary' }" <!-- アイコン部分だけ色変更 -->
  >
    Button
  </UButton>
</template>

2. 入力(UInput)

usingInputオプションを使うと、テキスト入力中はショートカットを有効/無効化できます。

index.vue
<script setup lang="ts">
import { z } from 'zod'
import { useForm } from '@nuxt/ui'

const schema = z.object({
  email: z.string().email() // メール形式のバリデーション
})

const { form, handleSubmit } = useForm({ schema })
</script>

<template>
  <form @submit.prevent="handleSubmit((values) => console.log(values))">
    <!-- UInputで入力フォーム -->
    <UInput v-model="form.email" label="Email" />
    <UButton type="submit">送信</UButton>
  </form>
</template>

3. テーブル(UTable)

UTableコンポーネントはTanStack Table(有名なテーブルライブラリ)の上に構築されており、useVueTableによって表を作るのに複雑なHTMLを何十行も書く必要がなくなります。

index.vue
<script setup lang="ts">
import { h, resolveComponent } from 'vue'
import type { TableColumn } from '@nuxt/ui'

const UBadge = resolveComponent('UBadge')

type Payment = {
  id: string
  date: string
  status: 'paid' | 'failed' | 'refunded'
  email: string
  amount: number
}

// データ例
const data = ref<Payment[]>([
  {
    id: '4600',
    date: '2024-03-11T15:30:00',
    status: 'paid',
    email: 'james.anderson@example.com',
    amount: 594
  },
  {
    id: '4599',
    date: '2024-03-11T10:10:00',
    status: 'failed',
    email: 'mia.white@example.com',
    amount: 276
  },
  {
    id: '4598',
    date: '2024-03-11T08:50:00',
    status: 'refunded',
    email: 'william.brown@example.com',
    amount: 315
  },
  {
    id: '4597',
    date: '2024-03-10T19:45:00',
    status: 'paid',
    email: 'emma.davis@example.com',
    amount: 529
  },
  {
    id: '4596',
    date: '2024-03-10T15:55:00',
    status: 'paid',
    email: 'ethan.harris@example.com',
    amount: 639
  }
])

// カラム定義
const columns: TableColumn<Payment>[] = [
  {
    accessorKey: 'id',
    header: '#',
    cell: ({ row }) => `#${row.getValue('id')}`
  },
  {
    accessorKey: 'date',
    header: 'Date',
    cell: ({ row }) => {
      return new Date(row.getValue('date')).toLocaleString('en-US', {
        day: 'numeric',
        month: 'short',
        hour: '2-digit',
        minute: '2-digit',
        hour12: false
      })
    }
  },
  {
    accessorKey: 'status',
    header: 'Status',
    cell: ({ row }) => {
      const color = {
        paid: 'success' as const,
        failed: 'error' as const,
        refunded: 'neutral' as const
      }[row.getValue('status') as string]

      return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () =>
        row.getValue('status')
      )
    }
  },
  {
    accessorKey: 'email',
    header: 'Email'
  },
  {
    accessorKey: 'amount',
    header: () => h('div', { class: 'text-right' }, 'Amount'),
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'))

      const formatted = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'EUR'
      }).format(amount)

      return h('div', { class: 'text-right font-medium' }, formatted)
    }
  }
]
</script>

<template>
  <UTable :data="data" :columns="columns" class="flex-1" />
</template>

4. モーダル(UModal)

モーダルを開いたときに表示する内容は、#contentスロットで設定します。
:dismissible="false"にすれば、外側をクリックしても閉じないようにできます。

index.vue
<script setup lang="ts">
const open = ref(false)

defineShortcuts({
  o: () => open.value = !open.value
})
</script>

<template>
  <UModal v-model:open="open">
    <UButton label="Open" color="neutral" variant="subtle" />

    <template #content>
      <Placeholder class="h-48 m-4" />
    </template>
  </UModal>
</template>

5. Figmaキットの活用

Nuxt UI v4では、2,000種類以上のコンポーネントが揃ったFigmaキットが無料で手に入ります。
これで、デザイナーとデベロッパーの連携がスムーズになりそうです。
https://www.figma.com/community/file/1544369209862884086

6. AIサポート(MCP Server & LLMs.txt)

生成AIを活用して、Nuxt UIのコンポーネント選択や実装をサポートできます。

MCP Server

bash
mcp find_component_for_usecase       # ユースケースに最適なコンポーネント提案
mcp implement_component_with_props   # props/slots付きでコンポーネント実装生成
mcp setup_project_with_template      # プロジェクト設定をガイド付き生成

LLMs.txt

質問時にLLMs.txtのURLを参照することができます。
AIが読みやすい形式のドキュメントで、AIがより正しく答えできるようになります。

以下はGPT-5の質問回答結果です:

あとがき

Nuxt UI v4を試してみたところ、前のProコンポーネントが無料になってて本当に嬉しいニュースです。特にUPricingTableやUAuthFormなどのコンポーネントは、色んなサイトでよく見かけるUIで、開発プロジェクトでもすぐに使えそうです。個人的には、FigmaキットとAI連携でデザインから実装までがスムーズに進むのが一番便利だと思いました。これから、Nuxt UI v4を活用していきたいと思います。

参考

ファースト・スクラッチTech Blog

Discussion