Receta · Básico · 15 min
Cómo hacer un CLAUDE.md que Claude Code sí respete
Qué poner y qué no en CLAUDE.md, dónde va cada archivo, imports con @ruta, /init y /memory, y una plantilla probada para un proyecto web.
Probado con Claude Code 2.1.316 · revisado
El problema
Escribes un CLAUDE.md enorme con todo lo que sabes del proyecto y Claude Code se salta la mitad. O al revés: no tienes ninguno y en cada sesión le vuelves a explicar cómo se ejecutan los tests. Las dos cosas tienen el mismo arreglo: un archivo corto, con solo lo que Claude no puede deducir del código, en el sitio correcto, y las reglas que no admiten excepciones fuera de él.
La solución
1. Genera un borrador con /init y empieza a borrar
Dentro de tu proyecto abre Claude Code y escribe:
/init
Claude analiza el código y crea un CLAUDE.md con comandos de compilación, tests y convenciones que descubre. Si ya tienes uno, propone mejoras en vez de sobrescribirlo. A partir de ahí el trabajo es sobre todo quitar líneas: la documentación oficial recomienda quedarse por debajo de 200 líneas por archivo, porque los archivos más largos gastan más contexto y se respetan peor.
2. Deja solo lo que Claude no puede ver en el código
Pon:
- Cómo comprobar el trabajo: el comando exacto de tests, tipos y lint, y cómo ejecutar un solo archivo de test.
- Dónde engaña el código: un patrón antiguo que está por todas partes pero no hay que copiar, o una carpeta que parece muerta y no lo está.
- Decisiones que no están en el repo: qué helper de errores se usa, cómo se despliega, qué necesita revisión.
- Todo lo que ya le has corregido dos veces.
No pongas:
- El árbol de carpetas, la lista de dependencias o un resumen de la arquitectura: Claude los lee del código (
/doctorpropone quitarlos). - Reglas vagas como «escribe buen código» o «formatea bien». Escribe reglas comprobables: «indentación de 2 espacios», «ejecuta
npm testantes de hacer commit». - Procedimientos largos de varios pasos (van a una skill, paso 5).
- Prohibiciones que no admiten excepciones (van a hooks o permisos, paso 6).
- Tus preferencias personales (van a
CLAUDE.local.md, paso 3).
3. Pon cada cosa en su nivel
Claude Code junta (no sustituye) todos estos archivos, del más general al más concreto:
| Nivel | Ruta | Para qué | Se comparte con |
|---|---|---|---|
| Organización | Linux/WSL: /etc/claude-code/CLAUDE.md · macOS: /Library/Application Support/ClaudeCode/CLAUDE.md | Normas de la empresa | Toda la organización |
| Usuario | ~/.claude/CLAUDE.md | Tus preferencias en todos los proyectos | Solo tú |
| Proyecto | ./CLAUDE.md o ./.claude/CLAUDE.md | Comandos y convenciones del equipo | El equipo, vía git |
| Local | ./CLAUDE.local.md | Tus URLs de prueba, datos de ejemplo | Solo tú (añádelo a .gitignore) |
| Subcarpeta | src/pagos/CLAUDE.md | Reglas de esa parte del código | El equipo |
Los archivos del directorio donde lanzas Claude y de los de arriba se cargan al arrancar; lo más cercano se lee al final. Los CLAUDE.md de subcarpetas se cargan bajo demanda, cuando Claude lee o edita un archivo de esa carpeta. Para que CLAUDE.local.md no se suba al repo:
echo "CLAUDE.local.md" >> .gitignore
Si una regla solo importa para ciertos archivos, mejor que una subcarpeta es una regla con paths en .claude/rules/, que solo entra en contexto cuando Claude toca archivos que coinciden:
---
paths:
- "src/api/**/*.ts"
---
- Valida los cuerpos de las peticiones con los esquemas de src/api/esquemas/
4. Separa en archivos con imports @ruta
Escribe @ruta/al/archivo en cualquier parte del CLAUDE.md y ese archivo se carga junto con él. Las rutas relativas se resuelven desde el archivo que importa (no desde la carpeta donde lanzas Claude) y se permiten hasta cuatro saltos de imports anidados. Importar ordena, pero no ahorra contexto: lo importado se carga entero junto al CLAUDE.md. Si quieres mencionar una ruta sin importarla, ponla entre comillas invertidas. La primera vez que un CLAUDE.md de proyecto importa algo de fuera del proyecto (por ejemplo @~/.claude/mis-notas.md), Claude Code te pide aprobarlo.
5. Mueve los procedimientos a skills
Un flujo de varios pasos (publicar una versión, preparar una migración) pesa en todas las sesiones si vive en CLAUDE.md. En una skill (.claude/skills/<nombre>/SKILL.md) Claude solo ve el nombre y la descripción hasta que la tarea la necesita. Si el flujo tiene efectos (desplegar, publicar), añade disable-model-invocation: true en su frontmatter para que solo se ejecute cuando tú escribas /<nombre>.
6. Mueve las reglas obligatorias a hooks y permisos
CLAUDE.md es contexto, no configuración obligatoria: Claude lo sigue casi siempre, pero puede decidir que una indicación no aplica. Si algo tiene que pasar siempre o nunca, haz que lo aplique Claude Code. Por ejemplo, «nunca leas .env» como regla de permisos en .claude/settings.json:
{
"permissions": {
"deny": ["Read(./.env)", "Read(./.env.local)", "Read(./secrets/**)"]
}
}
Las reglas deny valen en todos los modos de permisos y también bloquean cat .env. Para «ejecuta el formateador tras cada edición» o «no toques migrations/» usa un hook PostToolUse o PreToolUse (ver la guía oficial de hooks). Si te descubres añadiendo «IMPORTANTE» a una línea que Claude sigue ignorando, esa línea es un hook.
7. Copia esta plantilla para un proyecto web
Guárdala como CLAUDE.md en la raíz y cambia los comandos por los tuyos:
# Proyecto: tienda-web (Vite + React + TypeScript)
## Comandos
- Instalar: `npm ci`
- Servidor de desarrollo: `npm run dev` (http://localhost:5173)
- Un solo test: `npx vitest run src/ruta/archivo.test.ts`
- Todos los tests: `npm test`
- Tipos: `npx tsc --noEmit`
- Lint: `npm run lint`
## Cómo dar algo por terminado
- Pasa `npx tsc --noEmit` y los tests del archivo que tocaste.
- Cambios de interfaz: compruébalos en el navegador, no solo con tests.
## Convenciones (lo que no se ve en el código)
- Estilo: @docs/estilo.md
- Llamadas a la API solo desde `src/api/cliente.ts`; nunca `fetch` suelto en componentes.
- `src/legacy/` sigue en producción, pero no copies sus patrones en código nuevo.
## Trampas conocidas
- Los tests de integración necesitan `VITE_API_URL`; copia `.env.example` a `.env.local`.
- `npm run build` falla si hay imports circulares en `src/store/`.
## Git
- Ramas `feat/…` o `fix/…`; commits en español, en imperativo.
Y el archivo importado, docs/estilo.md:
# Estilo de código
- Indentación de 2 espacios, comillas simples, sin punto y coma.
- Componentes en PascalCase, un componente por archivo, exportación con nombre (no `export default`).
- Textos visibles en español neutro (tú, no vos).
Compruébalo
Dentro de una sesión, /context muestra la lista Memory files con los CLAUDE.md que se cargaron, y /memory los lista todos (también los que aún no existen) para abrirlos y editarlos. Desde la terminal puedes preguntarle directamente:
claude -p "¿Qué reglas de estilo tiene este proyecto? Responde en una línea"
Salida real con la plantilla de arriba y Claude Code 2.1.316:
Usa 2 espacios de indentación, comillas simples y nada de punto y coma; los componentes van en PascalCase, uno por archivo y con exportación con nombre (sin `export default`), y los textos visibles se escriben en español neutro, con «tú» y no «vos» (`docs/estilo.md`).
Las reglas de estilo solo están en docs/estilo.md, y con --output-format stream-json --verbose se ve que Claude no usó ninguna herramienta para leerlo: le llegó por el import @docs/estilo.md.
Por qué funciona
Claude Code lee los CLAUDE.md al empezar cada sesión y los entrega como un mensaje después del prompt de sistema, así que compiten por la atención con todo lo demás: cuanto más corto y concreto, mejor se sigue. Los imports se expanden antes de llegar al modelo, las reglas con paths y los CLAUDE.md de subcarpetas solo entran cuando hacen falta, y los hooks y permisos los ejecuta Claude Code, no el modelo, por eso no dependen de que «se acuerde». Fuentes: memoria de Claude Code y buenas prácticas.
Errores típicos
- Claude ignora reglas del final del archivo → el CLAUDE.md pasa de 200 líneas → quita lo que se deduce del código o muévelo a
.claude/rules/conpaths. - Claude obedece unas veces una regla y otras la contraria → hay dos instrucciones que se contradicen (por ejemplo, la de usuario y la de proyecto) → revisa todos los niveles;
/doctor prompt-auditbusca contradicciones. - El import no se carga → la ruta tiene espacios o está entre comillas o comillas invertidas → escapa los espacios con
\y no la entrecomilles. - El
CLAUDE.mdde una subcarpeta no aparece en/context→ es normal: se carga cuando Claude lee un archivo de esa carpeta. - Una regla desaparece tras
/compact→ la diste solo en la conversación → pásala al CLAUDE.md de la raíz, que se vuelve a leer tras compactar. - Tus notas personales acaban en el repo → las pusiste en
CLAUDE.md→ muévelas aCLAUDE.local.mdy añádelo a.gitignore.
Preguntas frecuentes
¿Dónde se pone el archivo CLAUDE.md?
En la raíz del proyecto (./CLAUDE.md o ./.claude/CLAUDE.md) para el equipo, y en ~/.claude/CLAUDE.md para tus preferencias en todos los proyectos. Ambos se cargan a la vez.
¿Cuántas líneas debe tener un CLAUDE.md?
La documentación oficial recomienda menos de 200 por archivo. Separarlo con imports no reduce el coste, porque lo importado se carga igual.
¿Qué diferencia hay entre CLAUDE.md y CLAUDE.local.md?
CLAUDE.md se sube a git y lo comparte el equipo; CLAUDE.local.md es solo tuyo, se lee después del CLAUDE.md de la misma carpeta y debe ir en .gitignore.
¿Sirve mi AGENTS.md?
Sí: Claude Code lee AGENTS.md cuando no hay ningún CLAUDE.md ni CLAUDE.local.md en tu carpeta o por encima. Si tienes ambos, pon @AGENTS.md dentro del CLAUDE.md.
¿Escribir «IMPORTANTE» o «SIEMPRE» ayuda?
Poco. Si una línea se sigue ignorando, o el archivo es demasiado largo o la regla no admite excepciones y debe ser un hook o una regla de permisos.