新しい機能ごとにUIコンポーネントをClaude Codeに手動で記述することは、クラスなしでCSSを書くようなもので、繰り返しが多く、一貫性がなく、チーム全体でスケールすることは不可能です。UI構築のためのClaude Codeスキルは、デザインシステムを実行可能なツールに変え、予測可能なパラメーターとボイラープレートなしでコンポーネント、レイアウト、スタイルを生成します。
UI構築のためのClaude Codeスキルとは?
Claude Codeスキルは、UI生成ロジックを再利用可能でバージョン管理されたツールとしてパッケージ化し、Claude CodeがModel Context Protocol (MCP) を介して発見・呼び出しできるようにします。「Tailwindで、左寄せの画像、右寄せのテキスト、プライマリボタンを持つレスポンシブなカードコンポーネントを作成してください」のような冗長なプロンプトを作成する代わりに、building-uiスキルを一度定義し、component: "card", layout: "image-left"のような簡潔なパラメーターで呼び出します。
各スキルは、以下を定義するSKILL.mdファイルで構成されています。
- ツール名と説明: スキルが何をするか、いつClaudeがそれを使用すべきか
- パラメータスキーマ: バリデーション付きの型安全な入力
- 例: Claudeをトレーニングするための具体的な使用パターン
- 実装: コードを生成する実際のハンドラ
公式リポジトリのbuilding-uiスキルは、コンポーネント、レイアウト、テーマ、フォームのパターンを提供します。これにより、アドホックなUI生成が体系的で再現可能なプロセスに変わります。

素のプロンプトに対する主な利点
- 一貫性: 常に同じコンポーネント構造
- 型安全性: Claudeは生成前にパラメータを検証
- バージョン管理: スキルはGitで管理され、追跡およびレビューが可能
- チーム共有: 1つのスキルがエンジニアリング組織全体にサービスを提供
- パフォーマンス: デザイントークンやスペーシングスケールを再説明する必要がない
最高の生産性で開発チームが協力して作業できる統合されたオールインワンプラットフォームが欲しいですか?
Apidogはあなたの全ての要求に応え、Postmanをはるかに手頃な価格で置き換えます!
building-uiスキルのセットアップ
ステップ1: Claude Codeをインストールし、MCPを有効にする
Claude Code CLIをまだインストールしていない場合:
npm install -g @anthropic-ai/claude-code
claude --version # 2.0.70以上である必要があります
MCP設定ディレクトリとファイルを作成します:
# macOS/Linux
mkdir -p ~/.config/claude-code
touch ~/.config/claude-code/config.json
# Windows
mkdir %APPDATA%\claude-code
echo {} > %APPDATA%\claude-code\config.json

ステップ2: building-uiスキルをクローンしてビルドする
git clone https://github.com/anthropics/skills.git
cd skills/skills/building-ui
npm install
npm run build
これにより、TypeScriptハンドラがdist/index.jsにコンパイルされます。
ステップ3: スキルをロードするようにMCPを設定する
~/.config/claude-code/config.jsonを編集します:
{
"mcpServers": {
"building-ui": {
"command": "node",
"args": ["/absolute/path/to/skills/building-ui/dist/index.js"],
"env": {
"UI_LIBRARY": "react",
"STYLE_SYSTEM": "tailwind",
"THEME_CONFIG": "~/project/design-tokens.json"
}
}
}
}
重要:
argsには絶対パスを使用してください。Claudeがプロセスを起動する際に相対パスは失敗します- スキルをグローバルに設定するために環境変数を設定します:
UI_LIBRARY:react,vue,svelteSTYLE_SYSTEM:tailwind,styled-components,css-modulesTHEME_CONFIG: デザイントークンファイルへのパス
ステップ4: インストールを確認する
claude
ロードされたら、実行します:
/list-tools
次のように表示されるはずです:
Available tools:
- building-ui:generate-component
- building-ui:create-layout
- building-ui:apply-theme
- building-ui:generate-form
ツールが表示されない場合は、ログを確認してください:
# macOS/Linux
tail -f ~/.cache/claude-code/logs/mcp.log
# Windows
type %APPDATA%\claude-code\logs\mcp.log
よくある問題:
- ENOENT:
dist/index.jsへのパスが間違っています - 環境変数不足: スキルがテーマ設定を読み込めません
- バージョン不一致: Claude CodeのバージョンがMCP機能をサポートしていません
スキルを用いた主要なUI構築パターン
building-ui スキルは、4つの主要なツールをエクスポートします。それぞれが構造化されたパラメータを受け入れ、生成されたコードを返します。
1. コンポーネント生成ツール
ツール名: building-ui:generate-component
ユースケース: 再利用可能なUIコンポーネントを作成
パラメータ:
component: コンポーネント名 (button, card, modal, input, select)variants: スタイルバリアントの配列 (primary, secondary, outline)size: small | medium | largecustomProps: 追加プロパティのレコードchildren: ブール値 (コンポーネントが子を受け入れるかどうか)
例: バリアントを持つボタンを作成
generate-componentツールを使用して、primary、secondary、outlineのバリアント、サイズmedium、および無効状態のサポートを持つボタンコンポーネントを作成します。
生成された出力 (React + Tailwind):
// Button.tsx
import React from 'react';
import clsx from 'clsx';
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'outline';
size?: 'small' | 'medium' | 'large';
}
export const Button: React.FC<ButtonProps> = ({
variant = 'primary',
size = 'medium',
disabled,
children,
className,
...props
}) => {
const baseClasses = 'font-semibold rounded-lg transition-colors';
const variantClasses = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
outline: 'border-2 border-blue-600 text-blue-600 hover:bg-blue-50'
};
const sizeClasses = {
small: 'px-3 py-1.5 text-sm',
medium: 'px-4 py-2 text-base',
large: 'px-6 py-3 text-lg'
};
return (
<button
disabled={disabled}
className={clsx(
baseClasses,
variantClasses[variant],
sizeClasses[size],
disabled && 'opacity-50 cursor-not-allowed',
className
)}
{...props}
>
{children}
</button>
);
};
スキルは、環境変数に基づいてTypeScriptの型、アクセシビリティ属性、およびスタイリングクラスを推論します。
2. レイアウト作成ツール
ツール名: building-ui:create-layout
ユースケース: レスポンシブなページレイアウトを生成
パラメータ:
type: grid | flex | stack | sidebarcolumns: カラム数 (グリッドの場合)gap: スペーシングスケール (0, 1, 2, 3, 4, 5, 6, 8, 10, 12)responsive: ブレークポイント設定を含むオブジェクトareas: 名前付きグリッドエリア (例: "header header", "sidebar main")
例: レスポンシブなサイドバーを持つダッシュボードレイアウト
create-layoutを使用して、折りたたみ可能なサイドバー、ヘッダー、メインコンテンツエリア、フッターを備えたレスポンシブなダッシュボードレイアウトを生成します。gap-4を使用し、サイドバーをデスクトップでは幅256px、モバイルでは全幅にします。
生成された出力:
// DashboardLayout.tsx
import React, { useState } from 'react';
import clsx from 'clsx';
interface DashboardLayoutProps {
header?: React.ReactNode;
sidebar?: React.ReactNode;
main: React.ReactNode;
footer?: React.ReactNode;
}
export const DashboardLayout: React.FC<DashboardLayoutProps> = ({
header,
sidebar,
main,
footer
}) => {
const [sidebarOpen, setSidebarOpen] = useState(false);
return (
<div className="min-h-screen flex flex-col">
{/* Header */}
<header className="bg-white shadow-sm border-b border-gray-200 z-10">
<div className="px-4 sm:px-6 lg:px-8 py-4">
{header}
</div>
</header>
<div className="flex flex-1">
{/* Mobile menu button */}
<button
className="lg:hidden fixed bottom-4 right-4 bg-blue-600 text-white p-3 rounded-full shadow-lg z-20"
onClick={() => setSidebarOpen(!sidebarOpen)}
>
☰
</button>
{/* Sidebar */}
<aside className={clsx(
'bg-gray-50 border-r border-gray-200',
'fixed lg:relative inset-y-0 left-0 z-30',
'w-64 transform transition-transform lg:translate-x-0',
sidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'
)}>
<div className="p-4">
{sidebar}
</div>
</aside>
{/* Main content */}
<main className="flex-1 p-4 sm:p-6 lg:p-8">
{main}
</main>
</div>
{/* Footer */}
{footer && (
<footer className="bg-gray-50 border-t border-gray-200 mt-auto">
<div className="px-4 sm:px-6 lg:px-8 py-4">
{footer}
</div>
</footer>
)}
</div>
);
};
スキルは、モバイルメニューロジック、ブレークポイント対応クラス、およびアクセシビリティ属性を自動的に追加します。
3. テーマ適用ツール
ツール名: building-ui:apply-theme
ユースケース: コンポーネント全体にデザインルールを適用
パラメータ:
component: ターゲットコンポーネント名colorScheme: light | dark | systemspacingScale: 0-12 (Tailwindスペーシングスケール)typography: フォントサイズ、ウェイト、フォントファミリーを含むオブジェクトcustomTokens: CSSカスタムプロパティのレコード
例: カードコンポーネントにダークテーマを適用
apply-themeを使用して、スレートカラーパレット、スペーシングスケール4、Interフォントファミリーでダークモード用のCardコンポーネントを設定します。
生成された出力:
// card-theme.ts
export const cardTheme = {
light: {
background: 'bg-white',
border: 'border-gray-200',
text: 'text-gray-900',
subText: 'text-gray-600'
},
dark: {
background: 'bg-slate-800',
border: 'border-slate-700',
text: 'text-slate-100',
subText: 'text-slate-400'
}
};
// Usage in Card.tsx
import { cardTheme } from './card-theme';
interface CardProps {
variant?: 'light' | 'dark';
children: React.ReactNode;
}
export const Card: React.FC<CardProps> = ({ variant = 'light', children }) => {
const theme = cardTheme[variant];
return (
<div className={clsx(
'rounded-lg p-4 border',
theme.background,
theme.border
)}>
{children}
</div>
);
};
スキルはTHEME_CONFIGファイルを読み取り、テーマ固有のトークンマップを生成します。THEME_CONFIGがJSONファイルを指している場合:
{
"colors": {
"primary": "#3B82F6",
"secondary": "#6B7280"
},
"fonts": {
"sans": "Inter",
"mono": "JetBrains Mono"
}
}
生成されたコードは、Tailwindのデフォルト値の代わりにこれらの正確な値を使用します。
4. フォーム生成ツール
ツール名: building-ui:generate-form
ユースケース: スキーマから検証済みフォームを作成
パラメータ:
fields: フィールド定義の配列 (name, type, label, validation)submitAction: 関数名またはAPIエンドポイントvalidationMode: onBlur | onChange | onSubmitlayout: vertical | horizontal | grid
例: 検証機能付きユーザー登録フォーム
generate-formを使用して、フィールド: name (テキスト、必須)、email (メール、必須)、password (パスワード、最小長8)、acceptTerms (チェックボックス) を持つユーザー登録フォームを作成します。/api/registerにonBlurバリデーションで送信します。
生成された出力:
// UserRegistrationForm.tsx
import React, { useState } from 'react';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm, SubmitHandler } from 'react-hook-form';
const schema = z.object({
name: z.string().min(1, '名前は必須です'),
email: z.string().email('無効なメールアドレスです'),
password: z.string().min(8, 'パスワードは8文字以上である必要があります'),
acceptTerms: z.boolean().refine(val => val === true, {
message: '利用規約に同意する必要があります'
})
});
type FormData = z.infer<typeof schema>;
export const UserRegistrationForm: React.FC = () => {
const [isSubmitting, setIsSubmitting] = useState(false);
const {
register,
handleSubmit,
formState: { errors },
trigger
} = useForm<FormData>({
resolver: zodResolver(schema),
mode: 'onBlur'
});
const onSubmit: SubmitHandler<FormData> = async (data) => {
setIsSubmitting(true);
try {
const response = await fetch('/api/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) throw new Error('登録に失敗しました');
// Handle success
console.log('ユーザー登録済み:', await response.json());
} catch (error) {
console.error('登録エラー:', error);
} finally {
setIsSubmitting(false);
}
};
return (
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4 max-w-md">
<div>
<label htmlFor="name" className="block text-sm font-medium text-gray-700">
Name
</label>
<input
id="name"
{...register('name')}
className={clsx(
'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500',
errors.name && 'border-red-500'
)}
/>
{errors.name && (
<p className="mt-1 text-sm text-red-600">{errors.name.message}</p>
)}
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
Email
</label>
<input
id="email"
type="email"
{...register('email')}
className={clsx(
'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500',
errors.email && 'border-red-500'
)}
/>
{errors.email && (
<p className="mt-1 text-sm text-red-600">{errors.email.message}</p>
)}
</div>
<div>
<label htmlFor="password" className="block text-sm font-medium text-gray-700">
Password
</label>
<input
id="password"
type="password"
{...register('password')}
className={clsx(
'mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500',
errors.password && 'border-red-500'
)}
/>
{errors.password && (
<p className="mt-1 text-sm text-red-600">{errors.password.message}</p>
)}
</div>
<div className="flex items-center">
<input
id="acceptTerms"
type="checkbox"
{...register('acceptTerms')}
className="h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
/>
<label htmlFor="acceptTerms" className="ml-2 block text-sm text-gray-900">
利用規約に同意します
</label>
</div>
{errors.acceptTerms && (
<p className="text-sm text-red-600">{errors.acceptTerms.message}</p>
)}
<button
type="submit"
disabled={isSubmitting}
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50"
>
{isSubmitting ? '登録中...' : '登録'}
</button>
</form>
);
};
スキルは、react-hook-form、zodバリデーション、アクセシビリティ属性、およびローディング状態を自動的に接続します。
高度な技術を使用した動的なUI生成
条件付きレンダリングロジック
一部のUIでは、パラメータに基づいて条件付きセクションが必要です。スキルはフィールド定義でconditionsをサポートしています:
"accountType"が"business"の場合にのみ"company"フィールドが表示されるユーザープロフィールフォームを生成します。
これにより、条件付きレンダリングを備えたフォームが生成されます:
{accountType === 'business' && (
<div>
<label htmlFor="company">会社</label>
<input id="company" {...register('company')} />
</div>
)}
コンポーネント構成
スキル呼び出しを連結して、複雑なUIを構築します:
まず、サイドバーとヘッダーを持つDashboardLayoutコンポーネントを生成します。次に、メトリクス用のStatCardコンポーネントを生成します。最後に、両方にダークテーマを適用します。
Claude Codeはこれらを順次実行し、呼び出し間でコンテキストを渡します。レイアウトコンポーネントはカードの生成時に利用可能であり、適切な統合を保証します。
実行時のテーマ切り替え
テーマ対応コードを出力するようにスキルを設定します:
{
"building-ui": {
"command": "node",
"args": ["dist/index.js"],
"env": {
"UI_LIBRARY": "react",
"STYLE_SYSTEM": "tailwind",
"THEME_CONFIG": "~/project/themes.json",
"SUPPORT_THEME_TOGGLE": "true"
}
}
}
これで、生成されたコンポーネントにはThemeProviderラッパーが含まれます:
// App.tsx
import { ThemeProvider } from './ThemeProvider';
import { DashboardLayout } from './DashboardLayout';
function App() {
return (
<ThemeProvider defaultTheme="light" enableSystem>
<DashboardLayout />
</ThemeProvider>
);
}
UI構築スキルのデバッグと反復
.claude-cacheで生成されたコードを表示
Claude Codeはスキルの出力をキャッシュします。それらを検査してください:
# macOS/Linux
cat ~/.cache/claude-code/last-skill-output.tsx
# Windows
type %APPDATA%\claude-code\last-skill-output.tsx
生成されたコードが期待と一致しない場合は、パラメータを調整してください。より具体的に指定します:
次のようにする代わりに: 「カードを生成してください」
次のようにします: 「16pxのパディング、8pxのボーダーラディウス、そしてさりげないボックスシャドウを持つカードを生成してください」
プロジェクトごとのスキルデフォルトを上書きする
プロジェクトのルートに.claude-ui-config.jsonを作成します:
{
"uiLibrary": "vue",
"styleSystem": "css-modules",
"themeConfig": "./design-tokens.json"
}
これは、そのプロジェクトに対してのみグローバルなMCP設定を上書きします。
スキルのバージョン管理
building-uiスキルを更新する際は、バージョンをタグ付けします:
cd skills/building-ui
npm version patch # またはminor/major
git tag -a v1.1.0 -m "Added support for Vue 3.5"
バージョンを固定するためにClaude Codeの設定を更新します:
{
"mcpServers": {
"building-ui": {
"command": "node",
"args": ["/path/to/skills/building-ui-v1.1.0/dist/index.js"]
}
}
}
これにより、互換性のない変更が本番ワークフローに影響を与えるのを防ぎます。
結論
UI構築のためのClaude Codeスキルは、自然言語を手術のような正確さで、本番環境対応のコンポーネント、レイアウト、テーマ、フォームに変換します。セットアップに15分投資するだけで、デザインの一貫性を強制し、ボイラープレートを排除し、機能開発を加速する再利用可能なツールキットを手に入れることができます。generate-component、create-layout、apply-theme、generate-formの4つのコアツールから始めて、特定のデザインシステムに合わせて拡張してください。
スキルがAPIを利用するUIを生成する際には、Apidogでそれらのエンドポイントを検証し、AIが構築したインターフェースが信頼できるバックエンドと通信することを保証してください。
