Descrever componentes de interface de usuário manualmente para o Claude Code a cada nova funcionalidade é como escrever CSS sem classes: repetitivo, inconsistente e impossível de escalar entre equipes. As Habilidades do Claude Code para construção de UI transformam seu sistema de design em ferramentas executáveis que geram componentes, layouts e estilos com parâmetros previsíveis e zero *boilerplate*.
O que são as Habilidades do Claude Code para Construção de UI?
As Habilidades do Claude Code empacotam a lógica de geração de UI em ferramentas reutilizáveis e versionadas que o Claude Code pode descobrir e invocar via Model Context Protocol (MCP). Em vez de criar *prompts* prolixos como *“Crie um componente de cartão responsivo com Tailwind, uma imagem alinhada à esquerda, texto alinhado à direita e um botão primário,”* você define uma habilidade `building-ui` uma vez e a chama com parâmetros concisos: `component: "card", layout: "image-left"`.
Cada habilidade consiste em um arquivo `SKILL.md` que define:
- Nome e descrição da ferramenta: O que a habilidade faz e quando Claude deve usá-la
- Esquema de parâmetros: Entradas com validação e tipagem segura
- Exemplos: Padrões de uso concretos para treinar Claude
- Implementação: O manipulador real que gera o código
A habilidade `building-ui` do repositório oficial fornece padrões para componentes, layouts, temas e formulários. Ela transforma a geração *ad-hoc* de UI em um processo sistemático e repetível.

Principais Vantagens sobre a Criação de *Prompts* Pura
- Consistência: A mesma estrutura de componente todas as vezes
- Tipagem segura: Claude valida os parâmetros antes da geração
- Controle de versão: Habilidades vivem no Git, rastreáveis e revisáveis
- Compartilhamento em equipe: Uma habilidade serve a toda uma organização de engenharia
- Performance: Não há necessidade de reexplicar *design tokens* ou escalas de espaçamento
Quer uma plataforma integrada, All-in-One para sua Equipe de Desenvolvimento trabalhar em conjunto com máxima produtividade?
Apidog entrega todas as suas demandas e substitui o Postman por um preço muito mais acessível!
Configurando a Habilidade *building-ui*
Passo 1: Instale o Claude Code e Habilite o MCP
Se você ainda não instalou o Claude Code CLI:
npm install -g @anthropic-ai/claude-code
claude --version # Deve ser >= 2.0.70
Crie o diretório e o arquivo de configuração do 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

Passo 2: Clone e Construa a Habilidade *building-ui*
git clone https://github.com/anthropics/skills.git
cd skills/skills/building-ui
npm install
npm run build
Isso compila os manipuladores TypeScript para `dist/index.js`.
Passo 3: Configure o MCP para Carregar a Habilidade
Edite `~/.config/claude-code/config.json`:
{
"mcpServers": {
"building-ui": {
"command": "node",
"args": ["/caminho/absoluto/para/skills/building-ui/dist/index.js"],
"env": {
"UI_LIBRARY": "react",
"STYLE_SYSTEM": "tailwind",
"THEME_CONFIG": "~/projeto/design-tokens.json"
}
}
}
}
Crítico:
- Use caminhos absolutos para `args`. Caminhos relativos falham quando Claude inicia o processo
- Defina variáveis de ambiente para configurar a habilidade globalmente:
- `UI_LIBRARY`: `react`, `vue`, `svelte`
- `STYLE_SYSTEM`: `tailwind`, `styled-components`, `css-modules`
- `THEME_CONFIG`: Caminho para o seu arquivo de *design tokens*
Passo 4: Verifique a Instalação
claude
Uma vez carregado, execute:
/list-tools
Você deve ver:
Ferramentas disponíveis:
- building-ui:generate-component
- building-ui:create-layout
- building-ui:apply-theme
- building-ui:generate-form
Se as ferramentas não aparecerem, verifique os logs:
# macOS/Linux
tail -f ~/.cache/claude-code/logs/mcp.log
# Windows
type %APPDATA%\claude-code\logs\mcp.log
Problemas comuns:
- ENOENT: Caminho incorreto para `dist/index.js`
- Missing env vars: A habilidade falha ao carregar a configuração do tema
- Version mismatch: A versão do Claude Code não suporta recursos MCP
Padrões Essenciais de Construção de UI com Habilidades
A habilidade `building-ui` exporta quatro ferramentas primárias. Cada uma aceita parâmetros estruturados e retorna código gerado.
1. Ferramenta Gerar Componente
Nome da ferramenta: `building-ui:generate-component`
Caso de uso: Criar componentes de UI reutilizáveis
Parâmetros:
component: Nome do componente (botão, cartão, modal, input, select)variants: Array de variantes de estilo (primary, secondary, outline)size: small | medium | largecustomProps: Registro de propriedades adicionaischildren: Booleano (se o componente aceita filhos)
Exemplo: Crie um botão com variantes
Use a ferramenta generate-component para criar um componente de botão com as variantes primary, secondary e outline, tamanho médio, e suporte para estado desabilitado.
Saída gerada (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>
);
};
A habilidade infere tipos TypeScript, atributos de acessibilidade e classes de estilo com base em suas variáveis de ambiente.
2. Ferramenta Criar Layout
Nome da ferramenta: `building-ui:create-layout`
Caso de uso: Gerar layouts de página responsivos
Parâmetros:
type: grid | flex | stack | sidebarcolumns: Número de colunas (para grid)gap: Escala de espaçamento (0, 1, 2, 3, 4, 5, 6, 8, 10, 12)responsive: Objeto com configurações de *breakpoint*areas: Áreas de grid nomeadas (ex: "header header", "sidebar main")
Exemplo: Layout de painel com barra lateral responsiva
Use create-layout para gerar um layout de painel responsivo com uma barra lateral recolhível, cabeçalho, área de conteúdo principal e rodapé. Use gap-4 e faça a barra lateral ter 256px de largura no desktop, largura total no celular.
Saída gerada:
// 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>
);
};
A habilidade adiciona automaticamente a lógica do menu móvel, classes sensíveis ao *breakpoint* e atributos acessíveis.
3. Ferramenta Aplicar Tema
Nome da ferramenta: `building-ui:apply-theme`
Caso de uso: Aplicar *design tokens* em componentes
Parâmetros:
component: Nome do componente alvocolorScheme: light | dark | systemspacingScale: 0-12 (escala de espaçamento do Tailwind)typography: Objeto com tamanhos de fonte, pesos, famíliascustomTokens: Registro de propriedades CSS customizadas
Exemplo: Aplique o tema escuro a um componente de cartão
Use apply-theme para configurar um componente Card para o modo escuro com paleta de cores slate, escala de espaçamento 4 e família de fontes Inter.
Saída gerada:
// 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'
}
};
// Uso em 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>
);
};
A habilidade lê seu arquivo `THEME_CONFIG` e gera mapas de *tokens* específicos do tema. Se `THEME_CONFIG` apontar para um arquivo JSON:
{
"colors": {
"primary": "#3B82F6",
"secondary": "#6B7280"
},
"fonts": {
"sans": "Inter",
"mono": "JetBrains Mono"
}
}
O código gerado usa esses valores exatos em vez dos padrões do Tailwind.
4. Ferramenta Gerar Formulário
Nome da ferramenta: `building-ui:generate-form`
Caso de uso: Criar formulários validados a partir de esquemas
Parâmetros:
fields: Array de definições de campo (nome, tipo, rótulo, validação)submitAction: Nome da função ou *endpoint* da APIvalidationMode: onBlur | onChange | onSubmitlayout: vertical | horizontal | grid
Exemplo: Formulário de registro de usuário com validação
Use generate-form para criar um formulário de registro de usuário com os campos: nome (texto, obrigatório), email (email, obrigatório), senha (senha, comprimento mínimo 8) e aceitarTermos (caixa de seleção). Envie para /api/register com validação onBlur.
Saída gerada:
// 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, 'Name is required'),
email: z.string().email('Invalid email address'),
password: z.string().min(8, 'Password must be at least 8 characters'),
acceptTerms: z.boolean().refine(val => val === true, {
message: 'You must accept the terms'
})
});
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('Registration failed');
// Lidar com o sucesso
console.log('User registered:', await response.json());
} catch (error) {
console.error('Registration 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">
Nome
</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">
Senha
</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">
Aceito os termos e condições
</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 ? 'Registrando...' : 'Registrar'}
</button>
</form>
);
};
A habilidade conecta automaticamente `react-hook-form`, validação `zod`, atributos de acessibilidade e estados de carregamento.
Geração Dinâmica de UI Usando Técnicas Avançadas
Lógica de Renderização Condicional
Algumas UIs precisam de seções condicionais com base em parâmetros. A habilidade suporta `conditions` nas definições de campo:
Gere um formulário de perfil de usuário onde o campo "empresa" aparece apenas se "tipoDeConta" for "negócio".
Isso produz um formulário com renderização condicional:
{accountType === 'business' && (
<div>
<label htmlFor="company">Empresa</label>
<input id="company" {...register('company')} />
</div>
)}
Composição de Componentes
Crie UIs complexas encadeando chamadas de habilidades:
Primeiro, gere um componente DashboardLayout com barra lateral e cabeçalho. Em seguida, gere um componente StatCard para métricas. Finalmente, aplique o tema escuro a ambos.
O Claude Code executa essas operações sequencialmente, passando o contexto entre as chamadas. O componente de layout está disponível ao gerar o cartão, garantindo a integração adequada.
Troca de Tema em Tempo de Execução
Configure a habilidade para emitir código sensível ao tema:
{
"building-ui": {
"command": "node",
"args": ["dist/index.js"],
"env": {
"UI_LIBRARY": "react",
"STYLE_SYSTEM": "tailwind",
"THEME_CONFIG": "~/projeto/themes.json",
"SUPPORT_THEME_TOGGLE": "true"
}
}
}
Agora, os componentes gerados incluem um *wrapper* `ThemeProvider`:
// App.tsx
import { ThemeProvider } from './ThemeProvider';
import { DashboardLayout } from './DashboardLayout';
function App() {
return (
<ThemeProvider defaultTheme="light" enableSystem>
<DashboardLayout />
</ThemeProvider>
);
}
Depurando e Iterando Habilidades de Construção de UI
Visualize o Código Gerado em `.claude-cache`
O Claude Code armazena em cache as saídas das habilidades. Inspecione-as:
# macOS/Linux
cat ~/.cache/claude-code/last-skill-output.tsx
# Windows
type %APPDATA%\claude-code\last-skill-output.tsx
Se o código gerado não corresponder às expectativas, refine seus parâmetros. Adicione mais especificidade:
Em vez de: *“Gerar um cartão”*
Use: *“Gerar um cartão com preenchimento de 16px, raio de borda de 8px e uma sombra sutil”*
Substituir Padrões de Habilidade Por Projeto
Crie `.claude-ui-config.json` na raiz do seu projeto:
{
"uiLibrary": "vue",
"styleSystem": "css-modules",
"themeConfig": "./design-tokens.json"
}
Isso substitui as configurações globais do MCP apenas para aquele projeto.
Versionando Habilidades
Ao atualizar a habilidade `building-ui`, marque as versões:
cd skills/building-ui
npm version patch # Ou minor/major
git tag -a v1.1.0 -m "Adicionado suporte para Vue 3.5"
Atualize a configuração do Claude Code para fixar as versões:
{
"mcpServers": {
"building-ui": {
"command": "node",
"args": ["/caminho/para/skills/building-ui-v1.1.0/dist/index.js"]
}
}
}
Isso evita que mudanças que quebram a compatibilidade afetem os fluxos de trabalho de produção.
Conclusão
As Habilidades do Claude Code para construir UI convertem linguagem natural em componentes, layouts, temas e formulários prontos para produção com precisão cirúrgica. Ao investir 15 minutos na configuração, você obtém um kit de ferramentas reutilizável que impõe consistência de design, elimina o *boilerplate* e acelera o desenvolvimento de recursos. Comece com as quatro ferramentas principais—`generate-component`, `create-layout`, `apply-theme` e `generate-form`—e, em seguida, estenda-as para o seu sistema de design específico.
Quando suas habilidades geram UIs que consomem APIs, valide esses *endpoints* com o Apidog para garantir que suas interfaces construídas por IA se comuniquem com *backends* confiáveis.
