Saltar al contenido
← artículos
Claude CodeHarness EngineeringAI CodingDeveloper Tools

CLAUDE.md: buenas prácticas, la guía completa

Qué va en CLAUDE.md, qué recortar, dónde vive cada archivo y cuánto te cuesta. Más la trampa del import que metió 70k tokens en cada sesión de un proyecto de 13 apps.

CLAUDE.md no es documentación. Es la parte de tu context window que ya gastaste antes de escribir una sola palabra.

Claude Code empieza cada sesión sin ningún recuerdo de tu proyecto. CLAUDE.md es la forma de arreglarlo: un archivo Markdown que Claude Code lee al inicio de cada sesión y mantiene en contexto hasta que la sesión termina. Escríbelo bien y Claude deja de repetir los mismos errores. Escríbelo mal y lo pagas en cada request, en tokens y en instrucciones que Claude sigue a medias.

La mayoría de los consejos sobre CLAUDE.md son un template. Esta guía son las decisiones: qué merece una línea, qué se recorta, en qué archivo va cada instrucción y cómo comprobar cuánto estás pagando de verdad. Aprendí la parte cara en una fintech de 13 apps que construí en 70 días, donde un CLAUDE.md que parecía liviano cargaba casi 70.000 tokens en cada sesión.

CLAUDE.md es contexto, no configuración

Si te equivocas en esto, nada más en el archivo funciona. La documentación de Anthropic lo dice sin vueltas: Claude “los trata como contexto, no como configuración obligatoria”. Claude lee tu CLAUDE.md como un ingeniero nuevo lee el documento de onboarding. Casi siempre lo sigue. No siempre. Y cuanto más contiene el archivo, menos se sigue.

Eso divide cada instrucción en dos tipos. La que necesita criterio (“filtra cada query por comercio”) va en CLAUDE.md, porque solo alguien que lee puede aplicarla. La que nunca se puede romper (“nunca ejecutes kubectl apply”) no tiene lugar en un archivo que Claude puede leer en diagonal. Va en un hook o en un linter, donde el chequeo corre aunque Claude no se acuerde de la regla. Más sobre eso abajo.

El CLAUDE.md de la raíz del proyecto también sobrevive a la compactación. Después de un /compact, Claude Code lo vuelve a leer del disco y lo inyecta otra vez. Todo lo demás que dijiste en el chat puede terminar resumido. El archivo se queda.

Dónde vive CLAUDE.md decide cuándo lo pagas

No hay un solo CLAUDE.md. Hay varios, y cargan en momentos distintos. Los archivos de tu directorio de trabajo y de cada carpeta por encima cargan al iniciar y se apilan, desde la raíz del sistema de archivos hasta donde abriste Claude, así que el más cercano se lee al final. Nada sobrescribe nada. Todo se concatena, y si dos archivos se contradicen, la documentación advierte que Claude “puede elegir uno arbitrariamente”.

Todos los lugares donde busca Claude Code

Verificado con la documentación de memoria de Claude Code el 6 de octubre de 2026.
ArchivoCuándo cargaÚsalo para
~/.claude/CLAUDE.mdCada sesión, cada proyectoTus hábitos: las herramientas que usas, cómo te gustan los commits
./CLAUDE.md o ./.claude/CLAUDE.mdCada sesión en este repoLas reglas del equipo. Va al repo junto con el código
./CLAUDE.local.mdCada sesión en este repo, solo para tiTus URLs de sandbox y datos de prueba. Ponlo en el .gitignore
subcarpeta/CLAUDE.mdCuando Claude abre un archivo ahí con Read, Edit o WriteReglas de un paquete de un monorepo
.claude/rules/*.mdAl iniciar, como el archivo del proyectoDividir un archivo grande por tema. Mismo costo
.claude/rules/*.md con paths:Cuando Claude abre un archivo que coincide con Read, Edit o WriteReglas que solo importan para algunos archivos
Archivo de política administradaCada sesión, para todos en la máquinaReglas de toda la empresa, definidas por el equipo de TI
Verificado con la documentación de memoria de Claude Code el 6 de octubre de 2026.

Vuelve a leer la segunda columna. Todo lo que carga al iniciar te cuesta en cada sesión, toque la tarea eso o no. Todo lo que carga bajo demanda solo cuesta cuando el trabajo llega ahí. La buena higiene de CLAUDE.md es, sobre todo, mover líneas del primer grupo al segundo. Un detalle: los archivos bajo demanda cargan cuando Claude abre un archivo con sus herramientas Read, Edit o Write. Un grep por Bash no cuenta, y suele ser la razón de que una regla “no haya cargado”.

En la fintech, mi CLAUDE.md tenía 124 líneas. Un resumen del proyecto, los comandos, once reglas críticas y después un set prolijo de tablas que apuntaban a veinte archivos por tema: roles de auth, schema de la base de datos, design tokens, componentes de UI, convenciones de testing, infraestructura. Parecía un índice.

No era un índice. Cada entrada estaba escrita como @.claude/ui/components.md, y en un CLAUDE.md la @ es un import. La documentación es clara sobre lo que eso significa: “Los archivos importados se expanden y se cargan en el contexto al iniciar, junto con el CLAUDE.md que los referencia.” Los imports pueden anidarse hasta cuatro niveles.

Lo que de verdad cargaba ese archivo de 124 líneas

124
líneasen el propio CLAUDE.md
20
importsescritos como @path en tablas
~175 KB
cargadosal inicio de cada sesión
69,8k
tokensmedidos con /context
El CLAUDE.md en sí tenía 1,8k tokens. Los imports más grandes eran componentes de UI (10,8k), infraestructura (10,6k) y design tokens (7,4k). Un bug fix en la API de pagos cargaba los tres.

Setenta mil tokens es más de un tercio de una context window de 200k, gastados antes del primer mensaje. Lo irónico es que yo ya había escrito la regla contra esto. Mi guía de AGENTS.md dice que hay que apuntar a la documentación detallada en lugar de pegarla en el archivo. Seguí la regla en espíritu y la rompí en la sintaxis.

El arreglo es un carácter. Otra vez la documentación: “El parsing de imports ignora los code spans de Markdown.” Pon la ruta entre backticks y deja de ser un import. Se vuelve texto que Claude puede decidir abrir.

@.claude/ui/components.md

  1. 01Un import
  2. 02Expandido en el contexto al iniciar
  3. 03Se paga en cada sesión, en cada tarea
  4. 04Se anida hasta cuatro niveles
  5. 05Siempre visible, así que siempre diluye

`.claude/ui/components.md`

  1. 01Un puntero
  2. 02Texto plano en el archivo
  3. 03Se paga solo si Claude lo abre
  4. 04Claude decide cuándo es relevante
  5. 05Se puede pasar por alto, así que no sirve para reglas obligatorias
Un carácter decide si un archivo te cuesta en cada sesión o solo cuando hace falta.

La última fila importa. Un puntero solo funciona si Claude decide abrirlo. Para una regla que tiene que aplicarse cada vez que Claude toca ciertos archivos, un puntero es demasiado débil y un import es demasiado caro. Justo para eso existen las rules con alcance por path.

Pon cada instrucción donde de verdad funciona

Cuando dejas de pensar en CLAUDE.md como el lugar para todo, la pregunta para cada línea pasa a ser: ¿cuál es el mecanismo más barato que igual hace que esto pase? Hay seis.

Dónde va cada tipo de instrucción

La instrucción es…Ponla enEjemplo de la fintech
Válida en todas partes y necesita criterioCLAUDE.mdLos datos de un comercio nunca llegan a otro
Válida solo para algunos archivos.claude/rules/ con paths:Design tokens, solo cuando hay un archivo de frontend abierto
Un procedimiento de varios pasosUna skillCrear una migration, correrla, agregar el test
Algo que nunca puede pasarUn hook o un linterNunca ejecutar kubectl apply en infra gestionada por Terraform
Válida solo para tiCLAUDE.local.md o ~/.claude/CLAUDE.mdTus hostnames HTTPS locales
Algo que Claude aprendió de una correcciónAuto memoryDeja que Claude lo escriba. Su índice carga hasta 200 líneas o 25 KB

Las skills merecen una frase más, porque son el mejor negocio de la lista. El cuerpo de una skill solo carga cuando la invocas o cuando Claude decide que encaja con la tarea. Un procedimiento de deploy de veinte pasos en CLAUDE.md te cuesta en cada sesión. El mismo procedimiento como skill te cuesta el día del deploy. En la fintech, ocho comandos del proyecto estaban en cada sesión como skills, a unos 20 tokens cada uno, hasta que alguien llamaba a uno. La guía de skill vs prompt vs memoria profundiza en esa división.

Las mayúsculas no imponen nada

Mi archivo tenía once reglas con la forma “NUNCA hagas X” y “SIEMPRE haz Y”. Gritarlas no cambió lo que eran: contexto que Claude lee y casi siempre sigue. Tres de ellas ni siquiera necesitaban el criterio de Claude. Necesitaban una máquina que dijera que no.

“NUNCA desactives reglas de ESLint” es una línea de config de ESLint: linterOptions: { noInlineConfig: true }, y todo comentario de disable inline deja de funcionar. “NUNCA uses valores arbitrarios de Tailwind” también es una regla de lint. Este sitio corre exactamente esa regla, y pnpm verify falla con p-[13px]. Y “NUNCA ejecutes kubectl apply” es un hook PreToolUse, que corre antes de que Claude ejecute un comando y puede bloquearlo:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.command' | grep -qE 'kubectl.* apply' && { echo 'Infra is managed by Terraform. Use terraform apply.' >&2; exit 2; } || exit 0"
          }
        ]
      }
    ]
  }
}

El exit code 2 bloquea la llamada y le devuelve el mensaje a Claude, que entiende el motivo y se pasa a Terraform. Ponlo en .claude/settings.json y la regla se cumple también el día en que Claude lee tu archivo en diagonal. Una regla que se puede imponer se debe imponer. CLAUDE.md es para las que no.

Qué merece una línea en CLAUDE.md

La documentación trae la mejor prueba que vi para saber cuándo agregar una línea. Agrégala cuando Claude comete el mismo error por segunda vez, cuando el code review atrapa algo que Claude debería haber sabido, cuando escribes la misma corrección que escribiste la sesión anterior, o cuando un compañero nuevo necesitaría el mismo contexto. Lo que el archivo no debería guardar es la historia alrededor del código: decisiones, personas, lo que se resolvió en cada reunión. Eso crece sin límite, y su lugar es un LLM wiki que el agente lee cuando lo necesita. Si no pasó nada de eso, la línea es una apuesta.

Qué va en el CLAUDE.md del proyecto

  • Obligatorio:
    Dos o tres líneas sobre qué es el proyectoEl stack y la forma del repo. Nada de pitch, nada de ensayo de arquitectura.
  • Obligatorio:
    Los comandos que Claude debe correrSetup, servidor de desarrollo, el comando que lo verifica todo. Claude no los puede adivinar.
  • Obligatorio:
    Convenciones que un buen ingeniero igual haría malDónde se traducen los errores de la API. Qué paquete se encarga del auth. Todo lo que no es estándar.
  • Obligatorio:
    Reglas que necesitan criterioAislamiento de datos, transacciones, lo que nunca sale del servidor. Escríbelas de forma que se puedan verificar.
  • Obligatorio:
    Punteros entre backticks a la documentación detalladaRutas que Claude abre cuando la tarea las necesita. No @imports.
  • Anti-pattern:
    Reglas que un linter o un hook podría imponerImponlas. Un archivo solo puede pedir.
  • Anti-pattern:
    Referencias largas sobre una parte del códigoMuévelas a una rule con alcance por path, para que carguen junto con los archivos que describen.
  • Anti-pattern:
    Consejos genéricos como 'escribe código limpio'Claude ya lo hace. La línea cuesta tokens y no cambia nada.
Si el archivo pasa de 200 líneas, Anthropic dice que la adherencia baja. El límite es por archivo, y cada import cuenta como un archivo aparte. El mío quedó por debajo. Sus veinte imports, no.

Escribe cada línea de forma que puedas verificar si Claude la siguió. Los ejemplos de la propia documentación son buenos: “Usa indentación de 2 espacios” en lugar de “Formatea bien el código”, “Corre npm test antes de hacer commit” en lugar de “Prueba tus cambios”. Si tú no puedes saber si una regla se rompió, Claude tampoco.

No dejes que /init lo escriba por ti

/init lee tu código y arma un borrador de CLAUDE.md. Es un buen punto de partida y un mal archivo final, y ahora hay datos que explican por qué. Evaluating AGENTS.md, un estudio de 2026 con agentes de código sobre issues reales de GitHub, encontró que los archivos de contexto en general no subieron la tasa de éxito y sumaron más de un 20% al costo de inferencia en promedio. Los archivos generados por un LLM rindieron un poco peor que no tener archivo. Los que escribieron los propios desarrolladores del repo rindieron apenas un poco mejor. Lo que ayudó fue lo que no es estándar, las convenciones que un modelo no adivinaría. El resumen del repositorio, justo lo que mejor hace /init, no ayudó.

Así que corre /init y después recorta. La documentación dice que hay que refinarlo “con instrucciones que Claude no descubriría por su cuenta”. Todo lo que Claude podría descubrir leyendo el código es una línea que pagas para repetir. La guía de AGENTS.md tiene la prueba de poda que uso: si quitar una línea no causaría ningún error, quítala.

Un ejemplo de CLAUDE.md: el archivo de la fintech, reescrito

Este es el archivo de 124 líneas como lo escribiría hoy. Mismo proyecto, las mismas reglas que importan, ningún import.

# Payment Platform

PIX payment gateway with on-chain settlement on the Liquid Network.
Turborepo + pnpm. Fastify 5, Drizzle, Zod. Next.js, Tailwind. PostgreSQL, Redis.

## Commands

- `pnpm setup:dev`: Docker, databases, migrations, seed
- `pnpm dev:https`: dev servers behind Caddy
- `pnpm verify`: format, lint, types, tests. Run it before every commit.

## Layout

- `apps/<domain>/api`: Fastify APIs for auth, exchange and payment
- `apps/<domain>/<app>`: Next.js frontends
- `packages/ui`, `packages/i18n`, `packages/auth`: shared code

## Rules that need judgment

- One merchant's data never reaches another merchant. Scope every query by merchant.
- Validate on the server. Never trust the client.
- Writes that touch more than one table run in a transaction.
- APIs return English messages plus a code from `ERROR_CODES`.
  Frontends translate with `getErrorMessage(code)`.

## Read when the task needs it

- Local setup: `.claude/setup/local-development.md`
- Git workflow: `.claude/git/workflow.md`
- Infrastructure: `infrastructure/README.md`

Menos de 40 líneas. El resto de los veinte archivos no desapareció. Se mueven a donde cargan junto con el trabajo que los necesita.

Adónde iría el resto de la documentación

  • .claude/
    • CLAUDE.mdsiempre// el archivo de arriba
    • settings.jsonobligatorio// el hook de kubectl
    • rules/
      • frontend.mdpaths// frontends y packages/ui: tokens, componentes, UX
      • database.mdpaths// apps/*/api/src/db/**: schema, migrations, entidades
      • auth.mdpaths// APIs y packages/auth: roles, scopes, permisos de rutas
      • testing.mdpaths// carpetas de test y e2e: convenciones de testing
      • pricing.mdpaths// apps/exchange/**: el motor de precios
    • skills/
      • new-migration/bajo demanda// el procedimiento, cargado cuando se usa

Una rule con alcance por path es un archivo Markdown normal con un campo más. Esta solo carga cuando Claude lee o edita un archivo dentro de una carpeta de base de datos:

---
paths:
  - "apps/*/api/src/db/**"
---

# Database

- Every table: a prefixed ID (`mer_`, `cus_`, `ord_`), `createdAt`, `updatedAt`,
  and an index on every foreign key.
- Tables are snake_case plural. Columns are snake_case.
- Relations live in a separate `relations.ts`.

La rule de frontend sigue siendo grande. Solo la referencia de componentes de UI ocupa 10,8k tokens. Pero ahora carga cuando Claude abre un componente de React, y se queda afuera cuando arregla un retry de un webhook. Ese es el trato: el costo no desapareció, se movió al momento en que compra algo.

Mide lo que cargas, no adivines

Mi primer cálculo para la fintech, a partir del tamaño de los archivos, fue de 45.000 tokens. /context en el repo viejo dijo 69.800. El cálculo se quedó corto por un tercio, hacia el lado que te deja bien parado. Mídelo. Claude Code ya trae las herramientas.

Dentro de una sesión de Claude Code

  1. Ver cada archivo de memoria que cargó y cuántos tokens ocupa

    /context
  2. Abrir y editar los archivos de memoria que encontró Claude Code

    /memory
  3. Encontrar instrucciones desactualizadas, faltantes o contradictorias (v2.1.283+)

    /doctor prompt-audit
Claude Code también avisa en el startup cuando un archivo, o todos juntos, pasan del tamaño recomendado.

Corre /context en tu repo principal hoy. Si los archivos de memoria ocupan más de unos pocos miles de tokens, abre el más grande y pregúntate, línea por línea, qué sesión lo necesitó de verdad.

CLAUDE.md vs AGENTS.md: con un archivo alcanza

Si tu repo lo tocan varios agentes, quizás ni necesites un CLAUDE.md. Desde la v2.1.277, Claude Code lee AGENTS.md como instrucciones del proyecto cuando no hay CLAUDE.md ni CLAUDE.local.md en tu carpeta o por encima, y Codex, Cursor, Copilot y otros también lo leen. Ojo con el segundo archivo: agregar un CLAUDE.local.md hace que Claude deje de leer tu AGENTS.md sin avisar. Si existen los dos tipos de archivo, Claude Code lee por defecto solo los CLAUDE.md, salvo que configures Project instructions en claude-md-and-agents-md desde /config.

La configuración limpia es un AGENTS.md compartido, más un CLAUDE.md que empieza con @AGENTS.md solo cuando Claude necesita líneas que los otros agentes no deberían ver. Ese import está bien, porque quieres el archivo completo en cada sesión. La guía de AGENTS.md tiene la tabla completa de qué agente lee qué.

Mantenlo al día o bórralo

Un CLAUDE.md equivocado es peor que ninguno, porque Claude lo sigue con confianza. Cambia el archivo en el mismo pull request que cambia la convención. Si pasas la base de datos de Prisma a Drizzle, la línea sobre Prisma muere en ese commit, y no tres meses después, cuando Claude escriba una query de Prisma.

Cada pocas semanas, corre /context, mira el número y recorta. El mejor CLAUDE.md que tengo es el de este sitio: un AGENTS.md corto en la raíz y unas pocas rules en .claude/rules/ que solo cargan para los archivos que describen. /context le da a su memoria de proyecto 2.000 tokens. La de la fintech era de 69.800. No está completo. Es barato, y es correcto.

CLAUDE.md, respuestas rápidas

¿Dónde va CLAUDE.md?

Para un proyecto, en la raíz del repo como CLAUDE.md o en .claude/CLAUDE.md, versionado junto con el código. Para reglas que aplican a todos tus proyectos, en ~/.claude/CLAUDE.md. Para notas personales sobre un proyecto, en CLAUDE.local.md en la raíz del repo, agregado al .gitignore. Un CLAUDE.md dentro de una subcarpeta solo carga cuando Claude trabaja en archivos de esa carpeta.

¿Qué tan largo debería ser CLAUDE.md?

La documentación de Anthropic recomienda quedarse por debajo de 200 líneas por archivo, porque los archivos más largos ocupan más contexto y reducen la adherencia.

Cuenta también los imports. Un archivo de 124 líneas con veinte @imports no es un archivo de 124 líneas. Corre /context para ver el tamaño real.

¿Claude lee CLAUDE.md cada vez?

Sí, al inicio de cada sesión, y se queda en contexto durante toda la sesión. Después de /compact, Claude Code vuelve a leer del disco el CLAUDE.md de la raíz del proyecto. Los CLAUDE.md en subcarpetas y las rules con alcance por path solo cargan cuando Claude lee o edita un archivo que coincide.

¿CLAUDE.md puede importar otros archivos?

Sí, con @ruta/al/archivo. Los archivos importados cargan al iniciar, así que cuestan lo mismo que pegarlos, y pueden anidarse hasta cuatro niveles. Para mencionar una ruta sin importarla, ponla entre backticks.

¿Por qué Claude ignora mi CLAUDE.md?

Primero verifica que haya cargado: /context lista cada archivo de memoria cargado al iniciar. Después revisa su tamaño y si dos archivos se contradicen, porque Claude puede elegir uno arbitrariamente.

Si una regla nunca se puede romper, deja de pedirla en un archivo. Usa un hook PreToolUse o un linter que la bloquee.

¿Cómo uso CLAUDE.md en un monorepo?

Deja en el archivo de la raíz las reglas que comparten todos los paquetes. Pon las reglas de cada paquete en un CLAUDE.md dentro de su carpeta o en una rule con alcance por path, para que solo carguen cuando Claude trabaja ahí. Si los archivos de otros equipos cargan en tus sesiones, sáltalos con claudeMdExcludes en .claude/settings.local.json.

¿Cuál es la diferencia entre CLAUDE.md y CLAUDE.local.md?

CLAUDE.md es del equipo y va al control de versiones. CLAUDE.local.md es tuyo, vive al lado y va al .gitignore. Los dos cargan al iniciar, y el local se agrega después del compartido.

¿Debo hacer commit de CLAUDE.md?

Haz commit del CLAUDE.md del proyecto. Describe cómo trabajar en el código y debería cambiar en los mismos pull requests que cambian el código. Deja lo personal en CLAUDE.local.md y lo secreto fuera de los dos.