Claude Code en monorepos puede desviarse cuando el repo es enorme. Aprende a definir límites, resúmenes locales y flujos repetibles para mantener las respuestas precisas.

Claude Code en monorepos puede sentirse impredecible por una razón sencilla: el repositorio es más grande de lo que el modelo puede mantener en memoria de trabajo a la vez.
“El contexto” es el conjunto de archivos, fragmentos, notas e instrucciones que se le han mostrado a Claude para esta tarea, además de lo que puede inferir de ellos. Cuando faltan detalles clave, Claude rellena huecos con conjeturas. En un repo grande, eso ocurre con más frecuencia.
Tres modos de fallo aparecen una y otra vez:
Primero, archivos perdidos. Un cambio que parece seguro en una carpeta en realidad depende de un tipo compartido, una regla de configuración o un paso de build definido en otro lugar. Si esa dependencia no está en el contexto, Claude puede editar con seguridad la cosa equivocada o detenerse temprano porque no ve la verdadera fuente de la verdad.
Segundo, similitud falsa. Los monorepos a menudo contienen múltiples paquetes que se parecen: dos módulos de auth, tres clientes de API, o varias apps React con estructuras de carpetas similares. Claude puede mezclar patrones entre ellos, actualizar un helper en el paquete equivocado o importar desde un nombre de módulo “casi correcto”.
Tercero, deriva temporal. Las grandes bases de código suelen tener formas antiguas y nuevas de hacer lo mismo. Si Claude solo ve archivos antiguos, puede copiar patrones obsoletos (opciones de config en desuso, APIs legadas) aunque el equipo ya haya cambiado.
Un ejemplo real común: pides un pequeño cambio en una UI de facturación y Claude edita un componente payments compartido usado por otras apps porque nunca vio el wrapper específico de la app que debería haberse cambiado.
El objetivo no es mostrarle a Claude todo el monorepo. El objetivo es proporcionar entradas más pequeñas y deliberadas que aún respondan la pregunta: el paquete que vas a cambiar, sus dependencias directas y una o dos “fuentes de la verdad” para tipos y configuración. Además, señala zonas de “no tocar” (otras apps, infra, código generado) y confirma qué paquete es el responsable del comportamiento.
La precisión depende menos de cuánto código pegues y más de cuán claramente describas el trabajo.
Empieza con el resultado que quieres: un arreglo específico, un refactor o una respuesta. Una “pregunta sobre el código” puede quedarse a alto nivel. Una solicitud de “hacer un cambio” necesita límites, entradas y comprobaciones de éxito.
Antes de compartir nada, escribe una frase que termine esta oración: “Después de que termines, debo poder…”. Por ejemplo: “ejecutar las pruebas unitarias del paquete X sin fallos” o “ver el nuevo campo en la respuesta de la API para el endpoint Y.” Esa frase se convierte en la estrella del norte cuando el repo es enorme.
Para cambios, comparte el conjunto más pequeño de artefactos que puedan probar que el cambio es correcto: el/los puntos de entrada, los tipos/interfaces o schema relevantes, una prueba que falle o un paso de reproducción con el resultado esperado, y cualquier configuración que afecte este camino (rutas, feature flags, build o reglas de lint). Si ayuda, añade un pequeño mapa de carpetas del paquete para que Claude entienda para qué sirve cada directorio.
Sé explícito sobre qué no mirar. Di: “Ignorar archivos generados, carpetas vendor, outputs de build, snapshots y lockfiles a menos que lo pida.” Eso evita tiempo perdido y ediciones en lugares que no revisarás.
También fija expectativas para la incertidumbre. Pide a Claude que marque suposiciones y desconocidos en lugar de adivinar. Por ejemplo: “Si no puedes ver dónde se llama esta función, dilo y propone 2 formas de localizarla.”
En un monorepo grande, la precisión baja cuando el modelo empieza a “ayudar” trayendo código cercano que no forma parte de la tarea. La solución es sencilla: define qué está dentro y qué está fuera antes de pedir cambios.
Empieza con un límite que coincida con cómo está organizado tu repo: un paquete, un servicio, una app o una librería compartida. Si el cambio es “actualizar la UI de checkout”, el límite probablemente sea un paquete de la app, no todos los lugares donde aparece la palabra “checkout”.
Señales que ayudan a Claude a quedarse en su sitio incluyen convenciones de carpetas (apps/, services/, packages/, libs/), manifiestos de paquete (exports y dependencias), puntos de entrada públicos (archivos index, componentes exportados, handlers) y tests (a menudo revelan la superficie prevista). Un README dentro de la carpeta puede ser el marcador de límite más rápido.
Los límites funcionan mejor cuando nombras los puentes entre ellos. Señala las interfaces específicas que Claude puede tocar y trata todo lo demás como fuera de límites. Los puentes típicos son contratos HTTP API, topics de eventos y payloads, tipos compartidos o un pequeño conjunto de funciones exportadas.
También nombra zonas “no tocar” siempre que el cambio no deba afectarlas. Las comunes son configuraciones de infraestructura y despliegue, lógica de seguridad y auth, facturación y pagos, migraciones de datos y esquemas en producción, y librerías compartidas usadas por muchos equipos.
Un detalle concreto de prompt que ayuda:
“Haz cambios solo dentro de packages/cart/ y sus tests. Puedes leer tipos compartidos en packages/types/ pero no los modifiques. No edites infra, auth o billing.”
La precisión mejora cuando proporcionas un mapa pequeño y estable del área que quieres cambiar. Un “resumen local” es ese mapa: lo suficientemente corto para leerse rápido, lo bastante específico para evitar conjeturas.
Mantén cada resumen en unas 10 a 20 líneas. Escríbelo como si le entregases el código a un compañero nuevo que solo necesita tocar este límite, no todo el repo. Usa lenguaje claro y nombres reales del código: carpetas, paquetes, funciones exportadas.
Un resumen útil responde cinco preguntas:
Añade una línea de “gotchas”. Aquí evitas errores costosos: cachés ocultos, feature flags, pasos de migración y cualquier cosa que falle silenciosamente.
Aquí tienes una plantilla compacta que puedes copiar:
Local summary: <package/service name>
Purpose: <1 sentence>
Scope: <what to touch> | Not: <what not to change>
Entry points: <files/routes/commands>
Public surface: <exports/endpoints/events>
Data sources: <tables/collections/queues/caches>
Conventions: errors=<how>, logging=<how>, tests=<where/how>
Gotchas: <flags/caching/migrations/edge cases>
Ejemplo: si editas un paquete de facturación, anota la función exacta que crea facturas, los nombres de tabla a los que escribe y la regla para errores reintentables. Entonces Claude puede enfocarse en ese límite en vez de deambular por auth compartido, config o paquetes no relacionados.
El mejor resumen es el que Claude ve cuando lo necesita. Ponlo junto al código que describe para que sea difícil de ignorar y fácil de actualizar. Por ejemplo, mantén un corto SUMMARY.md (o una sección en README.md) dentro de cada paquete, servicio o directorio de app en lugar de un documento gigante en la raíz del repo.
Una estructura simple y repetible ayuda. Manténlo lo bastante corto como para que la gente lo mantenga:
YYYY-MM-DD - <what changed in one sentence>Los resúmenes quedan obsoletos por razones predecibles. Trata las actualizaciones como actualizar una definición de tipo: parte de terminar el trabajo, no una tarea separada.
Actualiza el resumen cuando un refactor cambia estructura o nombres, un nuevo módulo se convierte en la forma principal de hacer algo, cambia un API/event/schema (aunque las pruebas sigan pasando), se mueven límites entre paquetes o se elimina/reemplaza una dependencia.
Un hábito práctico: cuando haces merge de un cambio, añade una línea “Last updated” indicando qué cambió. Herramientas como Koder.ai pueden ayudarte a mover más rápido en el cambio de código, pero el resumen es lo que mantiene futuros cambios precisos.
La precisión a menudo depende de cómo dosificas la conversación. Haz que Claude gane contexto en piezas pequeñas en lugar de adivinar a partir de un gran volcado.
Antes de cualquier edición, pide a Claude que describa lo que ve y qué necesita. Un buen mapa es corto: paquetes clave implicados, punto de entrada del flujo y dónde viven tests o tipos.
Prompt:
“Crea un mapa de este cambio: paquetes implicados, flujo principal y puntos probables de toque. No propongas código aún.”
Elige una porción estrecha: una feature, un paquete, un flujo de usuario. Declara el límite con claridad (por ejemplo: “Solo cambia packages/billing-api. No toques shared-ui o infra.”).
Un flujo que te mantiene en control:
Si a Claude le falta algo, debe decirlo. Pídele que escriba: (1) suposiciones que está haciendo, (2) qué las podría falsar, y (3) los archivos siguientes necesarios para confirmarlas.
Ejemplo: necesitas añadir un campo a una respuesta Invoice en un paquete. Claude solicita el handler, la definición DTO/tipo y una prueba. Compartes solo esos. Si usas un builder basado en chat como Koder.ai, aplica la misma regla: proporciona el conjunto mínimo de archivos fuente y expande solo cuando realmente sea necesario.
Tu mejor defensa contra ediciones erróneas es un pequeño “contrato” dentro del prompt: qué puede tocar Claude, cómo juzgarás el éxito y qué reglas debe seguir.
Empieza con un límite fácil de obedecer y verificar. Sé explícito sobre dónde se permiten ediciones y nombra las zonas “no tocar” para que no haya tentación de deambular.
Plantilla de contrato:
packages/payments/.packages/auth/, infra/ ni configs compartidos.Luego define comprobaciones de aceptación. Sin ellas, Claude puede producir código que parece correcto pero rompe las reglas reales del repo.
Las restricciones de estilo también importan. Dile a Claude qué patrones seguir y cuáles evitar, según lo que tu base de código ya hace. Por ejemplo: “Usa los helpers de error existentes en este paquete; no agregues dependencias nuevas; mantén nombres en camelCase; no introduzcas una nueva capa arquitectónica.”
Finalmente, exige un plan corto antes de cualquier edición:
“Antes de editar, lista los 3–5 archivos que esperas tocar y el cambio de comportamiento exacto. Espera aprobación.”
Ejemplo:
“Arreglar el redondeo de totales en invoices. Solo editar packages/billing/src/ y tests en packages/billing/test/. Aceptación: pnpm -C packages/billing test y typecheck. Sigue los utils de money existentes; no reescribir tipos API. Proporciona un plan de 4 pasos primero.”
La forma más rápida de obtener ediciones equivocadas en un monorepo es darle a Claude demasiado a la vez. Cuando pegas un gran montón de código, a menudo recurre a patrones genéricos en lugar del diseño específico que tu repo ya usa.
Otra trampa es dejar que adivine la arquitectura. Si no muestras puntos de entrada reales, puede elegir el primer archivo que parezca plausible y cablear la lógica allí. En la práctica, la precisión viene de un pequeño conjunto de archivos “fuente de la verdad” (módulos de entrada, routers, registradores de servicios, docs de límites de paquetes). Si esos no están en contexto, el modelo rellena huecos.
Los nombres también lo engañan. Los monorepos suelen tener paquetes como ui, ui-kit, shared-ui, o helpers duplicados como date.ts en dos lugares. Si mezclas snippets de ambos, Claude puede parchear un archivo mientras razona sobre el otro. Ejemplo: pides cambiar un estilo de botón, edita packages/ui/Button.tsx, pero la app importa packages/ui-kit/Button.tsx. El diff parece correcto, pero nada cambia en producción.
La configuración es otra fuente de deriva silenciosa. El comportamiento puede depender de env vars, feature flags, settings de build o tooling del workspace. Si no lo mencionas, Claude puede quitar una comprobación “rara” que solo importa cuando un flag está activo, o añadir código que rompe un paso de build.
Señales de alerta de deriva:
Trata los imports entre paquetes como una decisión, no como el comportamiento por defecto. Mantén las ediciones locales a menos que expandas el alcance intencionalmente.
La forma más rápida de obtener ediciones correctas es empezar con límites, no con volumen. Un buen prompt se siente un poco estricto: le dice a Claude dónde mirar, qué ignorar y qué significa “hecho”.
Antes de pegar código, escribe una breve introducción que fije el trabajo en un lugar del repo. Nombra el paquete, la carpeta exacta y el objetivo específico. Luego incluye un resumen local (propósito, dependencias clave, convenciones importantes) y el archivo de entrada que ancle el cambio.
Checklist:
<package>/<path>. Objetivo: <one sentence>. Ignorar todo lo demás a menos que se pida. <5-10 lines>. Archivo de entrada: <path/to/file>. <...>. No debe cambiar: <folders/files or APIs>. Mantener comportamiento: <what must stay true>.Si Claude propone cambios fuera de tu límite, trátalo como una señal: o aprietas el prompt, o expandes el límite a propósito y lo vuelves a declarar claramente.
Imagina que tu monorepo tiene apps/web-store (una app React) y packages/ui-kit (botones, inputs y estilos compartidos). Quieres una feature pequeña: añadir un botón “Save for later” en la página del carrito, usando un nuevo SaveIcon de ui-kit. Nada más debe cambiar.
Antes de pedir ediciones, crea dos resúmenes locales que actúen como límites. Manténlos cortos, específicos y opinativos sobre lo que importa.
# apps/web-store/LOCAL_SUMMARY.md
Purpose: Customer shopping UI.
Entry points: src/routes.tsx, src/pages/cart/CartPage.tsx
Cart rules: cart state lives in src/cart/useCart.ts
Do not touch: checkout flow (src/pages/checkout), payments, auth.
Tests: npm test -w apps/web-store
# packages/ui-kit/LOCAL_SUMMARY.md
Purpose: shared UI components.
Exports: src/index.ts
Icons: src/icons/*, add new icons by exporting from index.
Do not touch: theming tokens, build config.
Tests: npm test -w packages/ui-kit
Luego mantén el loop apretado:
CartPage y a los íconos de ui-kit. No editar checkout/auth.”CartPage, useCart, íconos de ui-kit, index de ui-kit).Después del cambio, documenta para que el contexto futuro siga siendo pequeño:
Si funciona bien para una persona pero no para el resto, lo que falta suele ser repetibilidad. Haz que la “buena higiene de contexto” sea la opción por defecto, no un hábito personal.
Guarda una plantilla de prompt que todos puedan copiar y rellenar. Manténla corta, pero estricta. Incluye el objetivo (qué significa “hecho”), el alcance permitido, límites duros (y por qué), un resumen local y un contrato de salida (plan primero, luego difs por archivo y tests).
Evita grandes revisiones mensuales que nadie hace. Adjunta las actualizaciones de resumen al trabajo normal: cuando un cambio altera comportamiento, dependencias o APIs, actualiza el resumen local en la misma PR.
Una regla simple: si un compañero tendría que preguntar “¿dónde vive esto?” o “¿qué depende de esto?”, el resumen está desactualizado.
Si prefieres un flujo orientado a chat, Koder.ai puede ayudar a que este estilo de iteración sea más seguro. El modo de planificación te ayuda a acordar alcance y límites antes de que ocurran ediciones, y los snapshots con rollback te permiten probar cambios sin quedarte atascado cuando una conjetura resulta errónea.
Claude se vuelve menos preciso cuando no puede “ver” la verdadera fuente de la verdad.
En un monorepo grande, el modelo a menudo pierde un archivo de dependencia, confunde dos paquetes similares o copia un patrón antiguo porque eso fue lo que estuvo en contexto.
No intentes incluir todo el repo. Empieza con el conjunto más pequeño que pueda demostrar que el cambio es correcto.
Un buen punto de partida es:
Comparte lo que ancla el comportamiento, no todo lo que tenga un nombre parecido.
Un conjunto práctico es:
Elige un límite que coincida con cómo está organizado tu repo: un paquete, app o servicio.
Luego decláralo explícitamente, incluyendo qué está fuera de alcance. Ejemplos de restricciones:
packages/cart/ y sus tests.”Porque los monorepos suelen contener módulos que se parecen (ui, ui-kit, shared-ui) y helpers duplicados (date.ts en varias ubicaciones).
Claude puede aplicar la idea correcta al paquete equivocado o importar desde un nombre de módulo “casi correcto”. Evítalo nombrando el paquete exacto y los puntos de entrada que quieres.
Un resumen local es un mapa corto del área exacta que quieres cambiar, normalmente 10–20 líneas.
Incluye:
Colócalo junto al código que describe para que sea fácil de encontrar y actualizar.
Una configuración simple por defecto:
SUMMARY.md o una sección pequeña en el README.md del paqueteDile a Claude desde el principio que marque suposiciones y desconocidos en lugar de adivinar.
Una regla útil:
Usa un bucle corto que obligue a ganar contexto en piezas pequeñas:
Escribe un mini “contrato” en tu prompt y hazlo ejecutable:
Esto facilita la revisión y reduce ediciones accidentales entre paquetes.