Nuxt UI v4 がついにリリース!無料で使える強力コンポーネントライブラリ
はじめに
2025年9月29日、Nuxt UI v4が正式リリースされました。
今回の大きなニュースは、これまで有料だった Nuxt UI Pro が完全無料で利用できるようになったことです。Vue/Nuxt開発者にとって、UIコンポーネントの選択肢が大幅に広がります。
公式ドキュメントや関連記事を調べて、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プロジェクトにインストール
新規プロジェクトの場合:
npm create nuxt@latest -- -t ui
既存プロジェクトの場合:
npm install @nuxt/ui
2. nuxt.config.tsにモジュールを追加
export default defineNuxtConfig({
modules: ['@nuxt/ui']
})
3. Tailwind CSSとNuxt UIをインポート
/* /app/assets/css/main.css */
@import "tailwindcss";
@import "@nuxt/ui";
4. nuxt.config.tsにcssを追加
export default defineNuxtConfig({
modules: ['@nuxt/ui']
+ css: ['~/assets/css/main.css']
})
5. アプリをラップ
<template>
<UApp>
<NuxtPage />
</UApp>
</template>
4. ローカル環境を起動
npm run dev
主要コンポーネント
1. ボタン(UButton)
Nuxt UI v4では、uiプロパティを使うことで、自分好みのスタイルに細かくカスタマイズできます。
<template>
<!-- UButtonコンポーネント: ボタンの色やアイコンを設定 -->
<UButton
icon="i-lucide-rocket" <!-- 左側にロケットアイコン -->
color="neutral" <!-- カラーバリエーション -->
variant="outline" <!-- 枠線のみのスタイル -->
:ui="{ leadingIcon: 'text-primary' }" <!-- アイコン部分だけ色変更 -->
>
Button
</UButton>
</template>
2. 入力(UInput)
usingInputオプションを使うと、テキスト入力中はショートカットを有効/無効化できます。
<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を何十行も書く必要がなくなります。
<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"にすれば、外側をクリックしても閉じないようにできます。
<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キットが無料で手に入ります。
これで、デザイナーとデベロッパーの連携がスムーズになりそうです。
6. AIサポート(MCP Server & LLMs.txt)
生成AIを活用して、Nuxt UIのコンポーネント選択や実装をサポートできます。
MCP Server

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を活用していきたいと思います。
Discussion