shadcn について
shadcn/ui を扱うためのスキルです。Radix UI または Base UI と Tailwind CSS を基盤とする React コンポーネントのソースをプロジェクトに追加し、カスタマイズできます。コーディングエージェント向けに CLI、コンポーネント、テーマ、レジストリの使い方を示します。
主な機能
- 01shadcn CLI によるプロジェクト初期化
- 02コンポーネントソースの追加と確認
- 03Radix UI または Base UI のプリミティブ選択
- 04テーマトークンとダークモードの設定
- 05コンポーネントレジストリの作成と管理
活用シーン
- 01React プロジェクトへの shadcn/ui 導入
- 02レジストリからのコンポーネント追加
- 03アプリのテーマカスタマイズ
- 04コーディングエージェントへのコンポーネントパターン提示
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ openai/ plugins --skill shadcnインストール後、Claude Code で/shadcnを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yaml
詳細
shadcn/ui
あなたは shadcn/ui のエキスパートです。shadcn/ui は、Radix UI のプリミティブと Tailwind CSS をベースに構築された、美しくデザインされ、アクセシブルで、カスタマイズ可能な React コンポーネントのコレクションです。コンポーネントは依存パッケージとしてインストールするのではなく、ソースコードとしてコードベースに直接追加します。
重要なコンセプト
shadcn/ui は、従来の意味でのコンポーネントライブラリではありません。パッケージとしてインストールするのではなく、CLI がコンポーネントのソースコードをプロジェクトにコピーするため、コードを完全に所有し、自由にカスタマイズできます。
CLI コマンド
初期化(非対話型 — 必ず使用してください)
重要:shadcn init はデフォルトでは対話型です。非対話型で初期化するには、必ず -d(デフォルト設定)を使用してください。
# Non-interactive init with defaults — USE THIS
npx shadcn@latest init -d
# Non-interactive with a preset (recommended for consistent design systems)
npx shadcn@latest init --preset <code> -f
# Non-interactive with explicit base library choice
npx shadcn@latest init -d --base radix
npx shadcn@latest init -d --base base-ui
# Scaffold a full project template (CLI v4)
AI Elements との互換性:プロジェクトで AI Elements を使用している、または使用する可能性がある場合は、必ず
--base radix(デフォルト)を使用してください。AI Elements のコンポーネントは Radix API に依存しており、Base UI では型エラーが発生します。
npx shadcn@latest init --template next -d
npx shadcn@latest init --template vite -d
オプション:
-d, --defaults— デフォルト設定を使用し、すべての対話型プロンプトをスキップします(CI/エージェントでの使用に必須)-y, --yes— 確認プロンプトをスキップします(ライブラリの選択はスキップしません。代わりに-dを使用してください)-f, --force— 既存の設定を強制的に上書きします-t, --template— プロジェクト全体のテンプレートを作成します(next、vite、react-router、astro、laravel、tanstack-start)--preset— デザインシステムのプリセット(色、テーマ、アイコン、フォント、角丸)を共有可能なコードとして適用します--base— プリミティブライブラリを選択します:radix(デフォルト)またはbase-ui--monorepo— モノレポ構成をセットアップします
警告:
-y/--yesだけでは、初期化は完全な非対話型になりません。コンポーネントライブラリの選択が引き続き表示されます。すべてのプロンプトをスキップするには、必ず-dを使用してください。
CLI v4 で非推奨:
--style、--base-color、--src-dir、--no-base-style、--css-variablesの各フラグは削除され、エラーになります。registry:buildとregistry:mcpのレジストリタイプも非推奨です。代わりにregistry:baseとregistry:fontを使用してください。
init コマンドは以下を実行します:
- フレームワークを検出します(Next.js、Vite、React Router、Astro、Laravel、TanStack Start)
- 必要な依存関係をインストールします(Radix UI、tailwind-merge、class-variance-authority)
components.jsonの設定を作成しますcn()ユーティリティ関数をセットアップします- テーマ設定用の CSS 変数を構成します
コンポーネントの追加
# Add specific components
npx shadcn@latest add button dialog card
# Add all available components
npx shadcn@latest add --all
# Add from a custom registry
npx shadcn@latest add @v0/dashboard
npx shadcn@latest add @acme/custom-button
# Add from AI Elements registry
npx shadcn@latest add https://elements.ai-sdk.dev/api/registry/all.json
オプション:
-o, --overwrite— 既存のファイルを上書きします-p, --path— インストール先のカスタムパスを指定します-a, --all— すべてのコンポーネントをインストールします--dry-run— ファイルを書き込まずに、追加される内容をプレビューします--diff— 既存のコンポーネントを更新する際、変更の差分を表示します--view— レジストリアイテムのソースコードをインラインで表示します
検索と一覧表示
npx shadcn@latest search button
npx shadcn@latest list @v0
ビルド(カスタムレジストリ)
npx shadcn@latest build
npx shadcn@latest build ./registry.json -o ./public/r
表示、情報、ドキュメント(CLI v4)
# View a registry item's source before installing
npx shadcn@latest view button
# Show project diagnostics — config, installed components, dependencies
npx shadcn@latest info
# Get docs, code, and examples for any component (agent-friendly output)
npx shadcn@latest docs button
npx shadcn@latest docs dialog
shadcn docsを使うと、コーディングエージェントはプリミティブを正しく使うためのコンテキストを取得できます。コード例、API リファレンス、使用パターンがインラインで返されます。
移行
npx shadcn@latest migrate rtl # RTL support migration
npx shadcn@latest migrate radix # Migrate to unified radix-ui package
npx shadcn@latest migrate icons # Icon library changes
# Migrate components outside the default ui directory
npx shadcn@latest migrate radix src/components/custom
shadcn/skills(CLI v4)
shadcn/skills は、コーディングエージェントがコンポーネントやレジストリを正しく扱うために必要なコンテキストを提供します。Radix と Base UI の両方のプリミティブ、更新された API、コンポーネントのパターン、レジストリのワークフローを網羅しています。このスキルは、CLI の使い方や呼び出すタイミング、渡すべきフラグを把握しているため、エージェントはデザインシステムに合ったコードを生成できます。
インストール:pnpm dlx skills add shadcn/ui
統合 Radix UI パッケージ(2026年2月)
new-york スタイルでは、個別の @radix-ui/react-* パッケージの代わりに、単一の radix-ui パッケージを使用するようになりました。
// OLD — individual packages
import * as DialogPrimitive from "@radix-ui/react-dialog"
// NEW — unified package
import { Dialog as DialogPrimitive } from "radix-ui"
既存のプロジェクトを移行するには、npx shadcn@latest migrate radix を実行してください。移行後、未使用の @radix-ui/react-* パッケージを package.json から削除してください。
Base UI のサポート(2026年1月)
shadcn/ui で、基盤となるプリミティブライブラリとして Radix UI に代わり Base UI を選べるようになりました。どちらのライブラリを選んでも、コンポーネントの見た目や動作は同じです。変わるのは基盤となる実装だけです。
初期化時に選択します:npx shadcn@latest init --base base-ui
CLI は、プロジェクトの設定に基づいて適切なコンポーネントのバリアントを自動的に取得します。
設定(components.json)
components.json ファイルで、プロジェクトにおける shadcn/ui の動作を設定します。
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "zinc", // Options: gray, neutral, slate, stone, zinc, mauve, olive, mist, taupe
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {
"v0": {
"url": "https://v0.dev/chat/api/registry"
},
"ai-elements": {
"url": "https://elements.ai-sdk.dev/api/registry"
}
}
}
名前空間付きレジストリ
プロジェクトに複数のレジストリを設定します。
{
"registries": {
"acme": {
"url": "https://acme.com/registry/{name}.json"
},
"private": {
"url": "https://internal.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}
名前空間構文を使ってインストールします。
npx shadcn@latest add @acme/header @private/auth-form
テーマ設定
CSS 変数
shadcn/ui ではテーマ設定に CSS カスタムプロパティを使用し、globals.css で定義します。
@theme inline {
--color-background: oklch(0.145 0 0);
--color-foreground: oklch(0.985 0 0);
--color-card: oklch(0.205 0 0);
--color-card-foreground: oklch(0.985 0 0);
--color-primary: oklch(0.488 0.243 264.376);
--color-primary-foreground: oklch(0.985 0 0);
--color-secondary: oklch(0.269 0 0);
--color-secondary-foreground: oklch(0.985 0 0);
--color-muted: oklch(0.269 0 0);
--color-muted-foreground: oklch(0.708 0 0);
--color-accent: oklch(0.269 0 0);
--color-accent-foreground: oklch(0.985 0 0);
--color-destructive: oklch(0.396 0.141 25.723);
--color-border: oklch(0.269 0 0);
--color-input: oklch(0.269 0 0);
--color-ring: oklch(0.488 0.243 264.376);
--radius: 0.625rem;
/* CLI v4: radius tokens use multiplicative calc instead of additive */
--radius-xs: calc(var(--radius) * 0.5);
--radius-sm: calc(var(--radius) * 0.75);
--radius-md: calc(var(--radius) * 0.875);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) * 1.5);
}
ダークモード
ダークモードにするには、<html> に dark クラスを指定します。
// app/layout.tsx
<html lang="en" className="dark">
または、切り替えに next-themes を使用します。
import { ThemeProvider } from 'next-themes'
<ThemeProvider attribute="class" defaultTheme="dark">
{children}
</ThemeProvider>
カスタムカラー
shadcn のデフォルトカラーに加えて、アプリケーション固有のカラーを追加します。
@theme inline {
/* shadcn defaults above... */
/* Custom app colors */
--color-priority-urgent: oklch(0.637 0.237 15.163);
--color-priority-high: oklch(0.705 0.213 47.604);
--color-status-done: oklch(0.723 0.219 149.579);
}
コンポーネントで使用します。
<span className="text-[var(--color-priority-urgent)]">Urgent</span>
// Or with Tailwind v4 theme():
<span className="text-priority-urgent">Urgent</span>
よく使われるコンポーネント
| コンポーネント | 用途 |
|---|---|
button | アクション、フォーム送信 |
card | コンテンツコンテナー |
dialog | モーダル、確認プロンプト |
input / textarea | フォームフィールド |
select | ドロップダウン |
table | データ表示 |
tabs | ビューの切り替え |
command | コマンドパレット(Cmd+K) |
dropdown-menu | コンテキストメニュー |
popover | フローティングコンテンツ |
tooltip | ホバー時のヒント |
badge | ステータス表示 |
avatar | ユーザープロフィール画像 |
scroll-area | スクロール可能なコンテナー |
separator | 視覚的な区切り |
label | フォームラベル |
sheet | スライドアウトパネル |
skeleton | 読み込み中のプレースホルダー |
Vercel における shadcn のデザイン方針
shadcn/ui は単なるコンポーネントソースジェネレーターではありません。Vercel のスタックでは、デフォルトのインターフェース言語です。「コンポーネントが動作する」だけで終わらせないでください。意図が明確で、情報密度が高く、一貫性のあるページを構成します。
プロダクト UI のデフォルトの美しさ
- プロダクト、ダッシュボード、AI、管理画面には、スタイルとして
new-yorkを優先します。 - ダッシュボード、AI アプリ、内部ツール、設定画面、開発者向けプロダクトでは、デフォルトでダークモードを使用します。ライトモードは、明らかにコンテンツ中心またはエディトリアルなプロダクトに限って使用します。
- インターフェースのテキストには Geist Sans、コード、メトリクス、ID、タイムスタンプ、コマンドには Geist Mono を使用します。
- ベースパレットには zinc、neutral、slate を優先します。
--color-primaryを通じて、アクセントカラーを 1 色使用します。 - コアとなるサーフェスにはトークンを使用します:
bg-background、bg-card、text-foreground、text-muted-foreground、border-border、ring-ring。場当たり的な 16 進数値は避けます。 - 角丸の一貫性を保ちます。デフォルトの
--radius: 0.625remは優れた基準です。 - ページごとに密度システムを 1 つ使用します:ゆったり(
gap-6/p-6/text-sm)またはコンパクト(gap-4/p-4/text-sm)。 - アイコンは控えめで、一貫性のあるものにします。Lucide アイコンは
h-4 w-4またはh-5 w-5を使用します。
まずはこれを選びましょう
| ユースケース | まずはこれを選ぶ | 理由 |
|---|---|---|
| 設定ページ | Tabs + Card + Form | 情報を明確にグループ化し、予測しやすい保存フローを実現します |
| データダッシュボード | Card + Badge + Table + DropdownMenu | カスタムのシェルを作らずに、概要、ステータス、密度の高いデータ、行ごとの操作に対応できます |
| CRUD テーブル | Table + DropdownMenu + Sheet + AlertDialog | 標準的なパターンで、一覧表示、操作、編集、破壊的操作の確認に対応します |
| 認証画面 | Card + Label + Input + Button + Alert | 入力フローに集中でき、エラーも適切に扱えます |
| グローバル検索 | Command + Dialog | キーボード操作を優先したすばやい検索を、確立されたインタラクションモデルで実現します |
| モバイルナビゲーション | Sheet + Button + Separator | 小さな画面にもきれいに適応する、コンパクトなナビゲーションシェルを提供します |
| 詳細ページ | ヘッダー + Badge + Separator + Card | 入れ子を増やさず、階層、メタデータ、補足コンテンツのバランスを保ちます |
| フィルター | Card サイドバー + Sheet + Select | デスクトップで常時表示するフィルターと、モバイルで折りたたみ可能なコントロールの両方に対応します |
| 空・読み込み中・エラー状態 | Card + Skeleton + Alert | 想定どおりに進まない状態にも、プレースホルダーテキストではなくデザインされた表示領域を用意します |
構成レシピ
- 設定ページ:グループごとの
Tabs+Card+Separator+ 保存アクション - 管理ダッシュボード:概要
Card+ フィルターバー +Table - エンティティの詳細:ヘッダー + ステータス
Badge+ メインのCard+ サイドのCard+ 破壊的操作にはAlertDialog - 検索中心の画面:すばやい検索には
Command、選択にはPopover、モバイルフィルターにはSheet - 認証・オンボーディング:中央配置の
Card+ ソーシャルログイン用のSeparator+ エラー表示用のインラインAlert - 破壊的操作のフロー:確認には
DialogではなくAlertDialog
避けるべきアンチパターン
- shadcn のプリミティブがあるのに、生の
button/input/select/divを使う Tabs/Table/Sheet/Dialogの代わりに、div rounded-xl border p-6を繰り返し使う- 複数のアクセントカラーが互いに競合している
Cardの中にCardを入れ、さらにその中にCardを入れる- あらゆる表示領域に、大きなグラデーション背景やグラスモーフィズムを使う
- 任意のスペーシング値や角丸値を混在させる
- 破壊的操作の確認に
AlertDialogではなくDialogを使う - 空・読み込み中・エラー状態をデザインせずにリリースする
- 基本的な表示領域にテーマトークンではなく、場当たり的な Tailwind パレットクラスを使う
カスタムレジストリの構築
プロジェクト間で共有できる独自のコンポーネントレジストリを作成します。
レジストリの種類(CLI v4)
| 種類 | 用途 |
|---|---|
registry:ui | 個別の UI コンポーネント |
registry:base | 完全なデザインシステムのペイロード — コンポーネント、依存関係、CSS 変数、フォント、設定 |
registry:font | ファーストクラスのレジストリアイテムとしてのフォント設定 |
1. registry.json を定義する
[
{
"name": "my-component",
"type": "registry:ui",
"title": "My Component",
"description": "A custom component",
"files": [
{
"path": "components/my-component.tsx",
"type": "registry:ui"
}
],
"dependencies": ["lucide-react"]
}
]
2. ビルドする
npx shadcn@latest build
# Outputs to public/r/my-component.json
3. 使用する
npx shadcn@latest add https://your-domain.com/r/my-component.json
コンポーネントの注意点
shadcn init によって Next.js の Geist フォントが機能しなくなる(Tailwind v4)
shadcn init は globals.css を書き換え、フォントの読み込みを妨げる循環自己参照 --font-sans: var(--font-sans) を追加する場合があります。Tailwind v4 の @theme inline は、実行時ではなく解析時に CSS カスタムプロパティを解決します。そのため、var(--font-geist-sans) も機能しません。Next.js はこの変数を実行時に className 経由で挿入するためです。
修正方法:@theme inline では、フォントファミリー名をリテラルで指定します。
/* In @theme inline — CORRECT (literal names) */
--font-sans: "Geist", "Geist Fallback", ui-sans-serif, system-ui, sans-serif;
--font-mono: "Geist Mono", "Geist Mono Fallback", ui-monospace, monospace;
/* WRONG — circular, resolves to nothing */
--font-sans: var(--font-sans);
/* ALSO WRONG — @theme inline can't resolve runtime CSS variables */
--font-sans: var(--font-geist-sans);
shadcn init の実行後は、必ず次の対応を行ってください。
@theme inlineのフォント宣言を、リテラルの Geist フォント名に置き換えます(上記参照)。layout.tsxで、フォント変数の className を<body>から<html>に移動します。
// layout.tsx — font variables on <html>, not <body>
<html lang="en" className={`${geistSans.variable} ${geistMono.variable}`}>
<body className="antialiased">
Avatar に size プロパティはありません
shadcn の Avatar コンポーネントは、size バリアントプロパティを受け付けません。サイズは Tailwind クラスで指定してください。
// WRONG — no size variant exists
<Avatar size="lg" /> // ❌ TypeScript error / silently ignored
// CORRECT — use Tailwind
<Avatar className="h-12 w-12">
<AvatarImage src={user.image} />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
// Small avatar
<Avatar className="h-6 w-6"> ... </Avatar>
これはほとんどの shadcn コンポーネントに当てはまります。サイズ指定にはバリアントプロパティではなく、Tailwind クラスを使います。再利用可能なサイズバリアントが必要な場合は、コンポーネントのソースで cva を使って追加してください。
よく使われるパターン
cn() ユーティリティ
すべての shadcn コンポーネントでは、条件に応じてクラスを結合するために cn() ユーティリティを使用します。
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
コンポーネントの拡張
ソースコードを所有しているため、コンポーネントを直接拡張できます。
// components/ui/button.tsx — add your custom variant
const buttonVariants = cva('...', {
variants: {
variant: {
default: '...',
destructive: '...',
// Add custom variants
success: 'bg-green-600 text-white hover:bg-green-700',
premium: 'bg-gradient-to-r from-purple-500 to-pink-500 text-white',
},
},
})
TooltipProvider でラップする
多くのコンポーネントでは、ルートに TooltipProvider が必要です。
// app/layout.tsx
import { TooltipProvider } from '@/components/ui/tooltip'
export default function RootLayout({ children }) {
return (
<html lang="en" className="dark">
<body>
<TooltipProvider>{children}</TooltipProvider>
</body>
</html>
)
}
フレームワークのサポート
- Next.js — 完全サポート(App Router + Pages Router)
- Vite — 完全サポート
- React Router — 完全サポート
- Astro — 完全サポート
- Laravel — 完全サポート(Inertia 経由)
- TanStack Start — 完全サポート
プリセット(CLI v4)
プリセットには、デザインシステムの設定全体(カラー、テーマ、アイコンライブラリ、フォント、角丸)が共有可能な単一のコードにまとめられています。1 つの文字列ですべてを設定できます。
# Apply a preset during init
npx shadcn@latest init --preset <code>
# Switch presets in an existing project (reconfigures everything including components)
npx shadcn@latest init --preset <code>
shadcn/create でカスタムプリセットを作成できます。公開する前に、実際のコンポーネントにカラー、フォント、角丸がどのように適用されるかをプレビューできます。
RTL サポート(2026)
CLI はインストール時に RTL 変換を処理します。
npx shadcn@latest migrate rtl
方向を指定するクラス(ml-4、left-2)を論理プロパティ(ms-4、start-2)に自動的に変換します。