TuBrief
구독 채널
비디오
커뮤니티

Cómo integrar de forma segura el código de interfaz creado por Claude Code en un proyecto existente

TuBrief 편집팀
2026년 9월 12일
0
Computing/Software

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

Español한국어English中文हिन्दीDeutschFrançaisالعربيةPortuguêsРусскийBahasa Indonesia日本語

관련 영상

Claude Code acaba de recibir su mejor actualización de diseño del año (y así es como puedes dominarla)10:58

Claude Code acaba de recibir su mejor actualización de diseño del año (y así es como puedes dominarla)

Chase AI

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

Cómo integrar de forma segura el código de interfaz creado por Claude Code en un proyecto existente

Abres Claude Code en la terminal, escribes /design y en pocos segundos aparece un borrador de la interfaz. Para un desarrollador solitario, esto es muy cómodo ya que requiere menos esfuerzo. El problema comienza en el momento en que abres ese código.

Los componentes de shadcn/ui que ya configuraste en el proyecto se ignoran por completo y se redacta una etiqueta <button> nativa desde cero. En lugar de los colores semánticos registrados en la paleta, se esparcen códigos hexadecimales arbitrarios como bg-[#1e293b] en cada archivo. Cada vez que creas una interfaz, pierdes 40 minutos corrigiendo rutas de importación desordenadas y eliminando estilos en línea.

No es una impresión tuya. Según un estudio de 2024 de GitClear que analizó 211 millones de líneas de commits, la proporción de código que se descarta por completo o se reescribe dentro de las dos semanas posteriores a la introducción de herramientas de IA aumentó casi al doble, pasando del 3.1% al 5.7%. La tasa de refactorización se desplomó del 25% a menos del 10%. La deuda técnica se acumula al mismo ritmo al que crece el código. Debes descartar la expectativa de que el modelo respetará por sí solo el sistema de diseño existente y atarle las manos a nivel de sistema.


Fijar las rutas de los componentes con un archivo de reglas del proyecto

La razón por la cual Claude Code ignora el código existente es simple: explora únicamente los archivos necesarios para ahorrar en la ventana de contexto. Si no se le impone ninguna restricción, el modelo dibuja interfaces combinando las etiquetas HTML más primitivas.

Gracias al almacenamiento en caché de prompts, el archivo de configuración en la raíz de la sesión se mantiene a un nivel equivalente al 10% del coste de entrada básico. No desaparece aunque reinicies o comprima la conversación. Si integras aquí las reglas de reutilización de componentes, puedes evitar que el modelo cree etiquetas nativas a su antojo.

Escribe las rutas de los componentes comunes y las reglas de estilo en el archivo CLAUDE.md de la raíz del proyecto.

`markdown

Design System Guidelines

  1. Component Reuse (STRICT)
  • DO NOT use raw DOM tags (, , ).
  • MUST import from @/components/ui:
    • Button: import { Button } from "@/components/ui/button"
    • Input: import { Input } from "@/components/ui/input"
    • Card: import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
    • Dialog: import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"
  • If a component does not exist in @/components/ui, ask to run: "npx shadcn@latest add ".
  1. Token Boundaries
  • NEVER use arbitrary hex codes or pixel widths: NO bg-[#...], NO w-[...px].
  • Use Semantic CSS variables:
    • Surfaces: bg-background, bg-card, bg-muted
    • Text: text-foreground, text-muted-foreground, text-primary
    • Borders: border-border, border-input

`

No es necesario pasar por completo un archivo CSS global de varios miles de líneas en cada prompt. Basta con extraer solo los nombres de los tokens desde la configuración de Tailwind y guardarlos en un JSON.

`javascript
// scripts/extract-tokens.mjs
import fs from 'fs';
import resolveConfig from 'tailwindcss/resolveConfig.js';
import tailwindConfig from '../tailwind.config.js';

const fullConfig = resolveConfig(tailwindConfig);
const semanticTokens = {
colors: Object.keys(fullConfig.theme.colors || {}).filter(
(name) => !['inherit', 'current', 'transparent'].includes(name)
),
spacing: Object.keys(fullConfig.theme.spacing || {}),
borderRadius: Object.keys(fullConfig.theme.borderRadius || {}),
};

if (!fs.existsSync('.claude')) {
fs.mkdirSync('.claude');
}

fs.writeFileSync(
'.claude/design-tokens.json',
JSON.stringify(semanticTokens, null, 2)
);

`

Configura este script en los eventos postinstall y predev de package.json.

`json
{
"scripts": {
"postinstall": "node scripts/extract-tokens.mjs",
"predev": "node scripts/extract-tokens.mjs"
}
}

`

La lista de clases disponibles se actualiza cada vez que se compila. Se elimina el tiempo de trabajo manual dedicado a corregir clases de estilo mal escritas.


Sustitución automática de estilos arbitrarios mediante scripts de ganchos (hooks)

Por mucho que escribas advertencias en el prompt, el modelo a veces arroja valores incorrectos. Si le lanzas una captura de pantalla y le pides que cree una interfaz, establecerá anchos fijos como w-[380px] en función de la proporción de la imagen. Esta es la causa principal de los desbordamientos de desplazamiento horizontal en pantallas móviles.

Para cumplir con los criterios WCAG 2.1 AA, debes especificar los estándares por resolución y realizar una validación estricta con un linter en el preciso instante en que se genera el archivo.

Área de verificación Criterio objetivo Clases de Tailwind obligatorias Condición de bloqueo
Móvil 390px (base) flex-col, w-full, grid-cols-1 Desplazamiento horizontal debido al uso de anchos fijos w-[...px]
Tableta 768px (md:) md:flex-row, md:grid-cols-2, md:p-6 Cuando la estructura móvil de 1 columna se mantiene en pantallas anchas
Escritorio 1440px (xl:) xl:max-w-7xl, mx-auto, xl:grid-cols-4 Cuando el contenedor de diseño crece sin límite en altas resoluciones
Modo oscuro Selector .dark bg-background, text-foreground Dejar clases predeterminadas como bg-white, text-black de forma aislada
Accesibilidad WCAG 2.1 AA aria-label, <main>, focus-visible:ring-2 Falta de texto alternativo para lectores de pantalla en botones de iconos

Para controlar a un modelo desobediente, lo más seguro es utilizar ganchos de ciclo de vida. Utilizando el gancho PostToolUse de Claude Code, se ejecuta un script en cuanto se escribe un archivo en el disco.

Registra el comando del gancho en .claude/settings.json.

`json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "node .claude/hooks/ast-lint-guard.mjs",
"timeout": 30
}
]
}
]
}
}

`

Ahora escribe el script de verificación. Captura códigos hexadecimales comunes con expresiones regulares para cambiarlos por tokens del proyecto y aplica las reglas mediante el plugin de ESLint para Tailwind.

`javascript
// .claude/hooks/ast-lint-guard.mjs
import fs from 'fs';
import readline from 'readline';
import { execSync } from 'child_process';

const rl = readline.createInterface({ input: process.stdin });
let inputBuffer = '';

rl.on('line', (line) => { inputBuffer += line; });
rl.on('close', () => {
try {
const payload = JSON.parse(inputBuffer);
const filePath = payload.tool_input?.file_path || payload.tool_input?.path;

if (!filePath || !/\.(tsx|jsx)$/.test(filePath) || !fs.existsSync(filePath)) {
  process.exit(0);
}

let code = fs.readFileSync(filePath, 'utf-8');
let changed = false;

const replacementMap = {
  '#ffffff': 'bg-background',
  '#000000': 'text-foreground',
  '#020817': 'bg-background',
  '#0f172a': 'bg-card',
  '#1e293b': 'bg-muted',
  '#64748b': 'text-muted-foreground',
  '#2563eb': 'bg-primary',
};

for (const [hex, token] of Object.entries(replacementMap)) {
  const regex = new RegExp(`(bg|text|border)-\x5b${hex}\x5b`, 'gi');
  if (regex.test(code)) {
    code = code.replace(regex, token);
    changed = true;
  }
}

if (changed) {
  fs.writeFileSync(filePath, code, 'utf-8');
}

execSync(`npx eslint "${filePath}" --rule "tailwindcss/no-arbitrary-value: error"`, {
  stdio: 'pipe',
});

process.exit(0);

} catch (error) {
const failureLog = error.stdout?.toString() || error.stderr?.toString() || error.message;
console.error([Lint Pipeline Block] Violación de reglas de estilo:\n${failureLog});
process.exit(1);
}
});

`

Instala el plugin del linter en el proyecto.

`bash
npm install -D eslint-plugin-tailwindcss

`

Si el script arroja un código de salida 1, Claude Code lee el registro de errores y reescribe el código usando clases semánticas en su siguiente turno. Se reduce el tiempo dedicado a lidiar con interfaces con diseños rotos durante la fase de QA.


Separar físicamente las vistas de la lógica de negocio

Cuando le pides a Claude Code que diseñe una interfaz, suele mezclar funciones fetch, objetos gigantescos de datos falsos y JSX en un solo archivo. Si luego quieres integrar una API real, tienes que desmontar incluso el código de renderizado.

El código de la vista no necesita saber cómo cambian los estados. Es más seguro dividir un directorio de funcionalidad en cuatro archivos y establecer primero el esquema de datos.

Primero, define el formato de los datos.

`typescript
// src/components/features/dashboard-card/schema.ts
import { z } from "zod";

export const MetricItemSchema = z.object({
id: z.string(),
label: z.string(),
value: z.string(),
changePercentage: z.number(),
trend: z.enum(["up", "down", "neutral"]),
});

export const DashboardCardSchema = z.object({
title: z.string().min(1),
metrics: z.array(MetricItemSchema),
});

export type DashboardCardData = z.infer;

export interface DashboardCardViewProps {
data: DashboardCardData;
isLoading?: boolean;
onActionClick?: (metricId: string) => void;
}

`

A continuación, asegúrate de prohibir el uso de estados internos al llamar a Claude Code desde la terminal.

`bash
claude "Crea src/components/features/dashboard-card/dashboard-card-view.tsx como un componente de UI puro que implemente DashboardCardViewProps de src/components/features/dashboard-card/schema.ts. No utilices bajo ningún concepto useState, useEffect o fetch en su interior; créalo de forma responsiva utilizando exclusivamente los props recibidos y elementos de @/components/ui."

`

Envuélvelo con un gancho (hook) al conectar los datos. Crea los datos simulados (mock data) y la función de llamada a la API real bajo la misma estructura.

`typescript
// src/components/features/dashboard-card/use-dashboard-card.ts
import { useQuery } from "@tanstack/react-query";
import { DashboardCardData } from "./schema";

const MOCK_DATA: DashboardCardData = {
title: "월간 활성 지표",
metrics: [
{ id: "m-1", label: "신규 유입", value: "1,240명", changePercentage: 12.5, trend: "up" },
{ id: "m-2", label: "이탈률", value: "2.1%", changePercentage: -0.4, trend: "down" },
],
};

export const useDashboardCard = (cardId: string, useMock = false) => {
return useQuery({
queryKey: ["dashboard-card", cardId],
queryFn: async () => {
if (useMock) {
return MOCK_DATA;
}
const res = await fetch(/api/dashboard/${cardId});
if (!res.ok) throw new Error("데이터 조회 실패");
return res.json();
},
});
};

`

Ensambla ambos en el componente contenedor.

`typescript
// src/components/features/dashboard-card/index.tsx
"use client";

import React from "react";
import { DashboardCardView } from "./dashboard-card-view";
import { useDashboardCard } from "./use-dashboard-card";

export function DashboardCardContainer({ cardId, useMock = false }: { cardId: string; useMock?: boolean }) {
const { data, isLoading } = useDashboardCard(cardId, useMock);

if (!data) return null;

return (
<DashboardCardView
data={data}
isLoading={isLoading}
onActionClick={(id) => console.log(id)}
/>
);
}

`

Antes de que el backend esté listo, pule la interfaz usando useMock={true}. Cuando la API esté completa, simplemente elimina la bandera. No hay razón para tocar ni una sola línea del código de la vista.


Aislamiento del árbol de trabajo y selección de cambios

Si interactúas largamente con el modelo en la terminal para ajustar la interfaz, el archivo de configuración global que estaba intacto suele terminar modificado o se crean archivos temporales innecesarios por todas partes en el directorio. Es mucho más cómodo dejar tu espacio de trabajo intacto y crear un directorio dedicado exclusivamente a experimentos.

Puedes utilizar Git worktree para ejecutar Claude Code en una carpeta completamente separada.

`bash
git worktree add ../saas-ui-sandbox -b experiment/ai-dashboard-ui
cd ../saas-ui-sandbox
claude

`

Si el experimento se arruina, puedes eliminar toda la carpeta sin pensarlo.

`bash
cd ../saas-platform
git worktree remove ../saas-ui-sandbox --force
git branch -D experiment/ai-dashboard-ui

`

Si obtuviste el resultado deseado, evita fusionar toda la rama y selecciona únicamente los fragmentos de código del archivo de vista mediante el modo interactivo.

`bash
git checkout main
git checkout -p experiment/ai-dashboard-ui -- src/components/features/dashboard-card/dashboard-card-view.tsx

`

Mientras revisas los bloques de código que aparecen en la terminal, presiona y para las partes que te agraden y rechaza las modificaciones extrañas con n.

Si una sesión supera los 5 turnos, el contexto se difumina y el modelo comienza a desvariar. Debes limpiar la sesión en cada ocasión:

  1. Revisión de tipos: Tan pronto como crees un componente individual, ejecuta inmediatamente npx tsc --noEmit. Pasa al siguiente prompt únicamente cuando haya 0 errores de tipado.
  2. Compresión de contexto: Si la conversación se alarga, escribe /compact sin vacilar para reducir el desperdicio de tokens.
  3. Vaciar la sesión: Una vez finalizado el trabajo de interfaz, deja un commit y borra por completo la memoria con /clear. Si las cosas se enredan, regresa al punto de control anterior con /rewind.

La capacidad superior de generación de un modelo y la posibilidad de que ese código ingrese a producción son cuestiones totalmente distintas. Si estrechas el canal de entrada con CLAUDE.md, validas el código de salida con ganchos de ciclo de vida y separas el espacio de trabajo con worktree, podrás evitar pasar la noche en vela arreglando el código arrojado por la IA.