
CLAUDE.md: buenas prácticas con ejemplo anotado
CLAUDE.md es el archivo más caro de tu repositorio. No en bytes. En repetición. Todo lo que pongas ahí se lee en el contexto de Claude al inicio de cada sesión y viaja con cada mensaje que envías después. Un CLAUDE.md hinchado es un impuesto que pagas cientos de veces al día sin darte cuenta.
En SkillProof testeamos configuraciones de Claude para ganarnos la vida, y a estas alturas hemos leído más archivos CLAUDE.md de los que nos gustaría admitir. La mayoría se equivoca de la misma manera: tratan el archivo como un vertedero de todo lo que el autor quiso alguna vez que Claude supiera. Filosofía de programación, preferencias de tono, una guía de estilo completa, tres párrafos sobre tener cuidado. Todo cargado, todo el tiempo, para cada petición, incluida esa en la que pediste a Claude renombrar una variable.
Esta guía es nuestro intento de arreglarlo. Para qué sirve realmente CLAUDE.md, un ejemplo completo anotado que puedes adaptar, qué mover a skills, y la aritmética que explica por qué todo esto importa.
Qué es CLAUDE.md y cuándo se carga
CLAUDE.md es el archivo de memoria de proyecto de Claude Code. Cuando arrancas una sesión en un directorio, Claude Code sube desde tu directorio de trabajo buscando archivos CLAUDE.md y carga lo que encuentra en el contexto del sistema. Tu archivo global en ~/.claude/CLAUDE.md también se carga, en todos los proyectos. Los archivos en subdirectorios se cargan cuando Claude trabaja con archivos de esos subdirectorios.
La parte que se le escapa a la gente: esto no es una lectura única. Los modelos de lenguaje no tienen estado, así que el contexto completo, incluido tu CLAUDE.md, se envía con cada petición de la conversación. Haz cuarenta preguntas en una sesión y el archivo se transmite cuarenta veces. El caché de prompts suaviza el coste en dólares, y llegaremos a los números reales, pero nada suaviza el coste de atención. Cada token de CLAUDE.md es un token que compite con tu código real por el foco del modelo.
Ese es el precio. Y compra algo real: Claude empieza cada sesión sabiendo ya tus comandos de build, las rarezas de tu arquitectura y las minas de tu codebase. Nadie tiene que pegar "usamos pnpm, no npm" por novena vez. La pregunta nunca es si tener un CLAUDE.md. Es qué se gana un sitio en él.
La regla de oro: hechos en CLAUDE.md, comportamiento en skills
Aquí va la tesis de todo este artículo, y el único filtro que arregla la mayoría de archivos malos:
CLAUDE.md es para hechos sobre este proyecto. Los skills son para comportamiento reutilizable.
Un hecho sobre este proyecto: "los precios se guardan como céntimos enteros". Claude no puede adivinar eso. Ninguna cantidad de inteligencia general lo saca de la nada, y equivocarse corrompe datos. Va en CLAUDE.md, cargado permanentemente, porque es relevante para casi cualquier cambio que toque dinero.
Comportamiento reutilizable: "al revisar código, comprueba primero el manejo de errores, luego seguridad, luego nombres". Eso no es un hecho sobre tu proyecto. Es un procedimiento, aplica a todos los proyectos que toques en tu vida, y solo es relevante cuando estás revisando código de verdad. Ponlo en CLAUDE.md y lo pagas durante cada mensaje de commit, cada retoque de CSS, cada "¿qué hace esta función?". Ponlo en un skill y te cuesta una línea de metadatos hasta el momento en que ocurre una revisión de verdad, y entonces las instrucciones completas se cargan bajo demanda.
La mayoría de la gente lo mete todo en CLAUDE.md porque es el archivo que conoce. Está ahí, funciona a la vista, y el coste es invisible porque ninguna factura dice jamás "has pagado por tu guía de estilo 4.000 veces este mes". Pero el coste es real, y la división es casi mecánica en cuanto haces dos preguntas sobre cualquier instrucción. ¿Es cierta solo en este proyecto? ¿Es relevante para la mayoría de peticiones? Dos síes: CLAUDE.md. Cualquier otra cosa: un skill, o la papelera.
Hay una segunda razón para la división que no tiene nada que ver con tokens. Las instrucciones de un archivo siempre cargado compiten entre sí. Hemos visto un CLAUDE.md de 2.000 palabras donde la regla genuinamente importante ("nunca ejecutes db:push contra staging") estaba en el párrafo once, debajo de un sermón sobre código limpio. Claude sigue las listas largas de instrucciones igual que las personas: los puntos afilados se diluyen entre el relleno. Los archivos cortos se obedecen. Los largos se ojean por encima.
Un ejemplo de CLAUDE.md anotado para una web app mediana
Aquí tienes un ejemplo completo para una tienda en Next.js, ficticia pero realista. Las anotaciones explican por qué cada sección se gana su asiento permanente en el contexto. Ocupa unas 350 palabras, alrededor de 500 tokens, y defenderíamos que nada de lo que contiene es recortable.
# Acme Storefront
Next.js 14 (App Router) + TypeScript. Postgres via Prisma. Deployed on Vercel.
<!-- One line of stack. Claude infers most of this from package.json anyway;
this just saves it the lookup. Do not write paragraphs here. -->
## Commands
- `pnpm dev` — local server on :3000 (needs `docker compose up db` first)
- `pnpm test` — unit tests (Vitest). Integration: `pnpm test:int` (slow, needs db)
- `pnpm lint && pnpm typecheck` — run both before calling any task done
- Migrations go through `pnpm db:migrate`. NEVER `db:push` outside local.
<!-- Commands earn their place because Claude runs them dozens of times per
session, and a wrong guess (npm vs pnpm) wastes a round-trip every time.
The db:push line is here because the failure is irreversible. -->
## Architecture facts you can't guess
- `src/app` is routes only. All logic lives in `src/modules/<domain>`.
- API routes are thin wrappers over `src/modules/*/service.ts`. No logic in routes.
- Auth is Clerk, but `userId` in services is OUR internal id, not Clerk's.
Map with `getInternalUser()`.
- Prices are integer cents everywhere. Formatting lives in `lib/money.ts`.
- Feature flags come from `flags.ts`, not env vars.
<!-- The test for this section: would a skilled new hire get it wrong on
day one? The Clerk id mismatch has caused real bugs; that is exactly
the kind of fact worth paying for on every request. -->
## Conventions that differ from defaults
- Named exports only. Legacy violations exist in `src/legacy`; don't add new ones.
- Server components by default. `"use client"` needs a comment saying why.
- Zod schemas live next to services; infer types from them, never hand-write both.
<!-- Only conventions that DIFFER from what Claude would do anyway.
"Use TypeScript strict mode" when tsconfig already says so is a wasted line. -->
## Gotchas
- `src/legacy/*` is frozen. Don't refactor it or import from it in new code.
- CI runs Node 20. `pnpm test:int` fails on 22; use `nvm use` first.
<!-- Each line here represents an hour someone actually lost. -->
## Definition of done
Lint, typecheck, and unit tests pass, and you state which of them you ran.
<!-- One sentence. Not a philosophy of quality. -->
Fíjate en lo que falta. Ningún "escribe código limpio y mantenible". Ninguna instrucción de tono. Ninguna explicación de qué es Next.js. Ninguna regla de lint que el linter ya impone mecánicamente. Cada línea es o un comando que Claude ejecutará, o un hecho que no puede inferir, o una frontera que, si se cruza, cuesta dinero real u horas reales.
Qué mover a skills
Si tu CLAUDE.md actual tiene 1.500 palabras, el exceso suele caer en unos pocos cubos reconocibles, y cada cubo tiene un hogar con forma de skill. Algunos ejemplos de nuestro propio catálogo, todos instalados y testeados en máquinas limpias antes de listarlos:
Ceremonia de git. Nombres de ramas, formato de mensajes de commit, plantillas de descripción de PR, cuándo hacer squash. Esto es comportamiento, es idéntico en todos tus proyectos y solo es relevante cuando estás haciendo commits de verdad. El skill git-workflow que testeamos cubre exactamente este ámbito, y sacarlo de CLAUDE.md suele ahorrar entre 200 y 400 palabras de texto siempre cargado.
Checklists de revisión. Las instrucciones de "cuando pida una revisión, comprueba X y luego Y" son el okupa clásico de CLAUDE.md. Son largas, son procedimentales y están dormidas el 95% del tiempo. code-review-checklist carga su checklist solo cuando hay una revisión en marcha, que es exactamente la gracia del formato de skill.
Disciplina de debugging. Instrucciones como "reproduce antes de arreglar, enuncia tu hipótesis, verifica después" describen una metodología, no tu proyecto. systematic-debugging empaqueta esa metodología y se queda fuera del contexto mientras haces cualquier cosa que no sea perseguir un bug.
La regla general: si pudieras copiar el párrafo en el CLAUDE.md de otro proyecto sin editarlo, no es un hecho sobre tu proyecto y no debería vivir ahí. Extráelo. Escribir tu propio skill lleva unos veinte minutos con nuestra guía, y son los veinte minutos con más palanca disponibles para cualquiera cuyo CLAUDE.md haya pasado de una pantalla.
PACK INICIAL GRATIS
Hemos agrupado cinco skills testeados que absorben el relleno más común de CLAUDE.md: flujo de git, checklists de revisión, disciplina de debugging y más. Instálalos y borra los párrafos correspondientes de tu archivo.
Consigue el pack inicial gratisAntipatrones que vemos una y otra vez
Revisamos muchas configuraciones, y los mismos cinco fallos aparecen en bucle.
La novela. Un CLAUDE.md de 3.000 palabras que se lee como un manual de ingeniería. Alguien tuvo una mala experiencia, añadió un párrafo, tuvo otra, añadió otro, y nunca borró nada. El archivo solo crece. Más allá del coste en tokens, los archivos así entierran las dos reglas que de verdad importan bajo veinte que no, y el cumplimiento de Claude con todas ellas cae en bloque.
Comandos caducados. El archivo dice npm run test:unit, el script se renombró a pnpm test hace ocho meses, y ahora Claude ejecuta con toda confianza un comando que falla, lee el error, hurga en package.json y se recupera. En cada sesión. Estás pagando por la documentación equivocada y pagando otra vez para que Claude la esquive. Un CLAUDE.md erróneo es peor que ningún CLAUDE.md, porque Claude se lo cree.
Reglas de lint duplicadas. "Usa comillas simples. Sin variables sin usar. Longitud máxima de línea 100." Tu configuración de ESLint ya impone esto mecánicamente, con mejor cobertura de la que tendrá jamás la atención de un LLM. Repetir en prosa reglas que la máquina ya impone es puro desperdicio. La única excepción: reglas que las herramientas no pueden detectar, como "no importes desde src/legacy", que sí merecen quedar por escrito.
La sección de "sé útil". "Escribe código limpio. Piensa bien antes de hacer cambios. Sé minucioso pero conciso." Vemos alguna variante de esto en la mitad de los archivos que revisamos, y no hace nada. Claude ya lo está intentando. Las instrucciones de vibras sin contenido comprobable son lo primero que hay que borrar, y su único efecto medible son los tokens que queman.
Autobiografía. Descripciones largas de qué hace el producto, quiénes son los usuarios, la misión de la empresa. De vez en cuando un hecho de producto importa para decisiones de código ("nuestros usuarios tienen conexiones rurales lentas, el tamaño del bundle es una restricción real"). Quédate con esa frase. Recorta el pitch deck.
Las matemáticas de los tokens
Hagamos la aritmética que la gente se salta, porque los números son lo que nos convirtió en minimalistas.
Un CLAUDE.md de 3.000 palabras son unos 4.000 tokens. Viaja con cada petición, así que una sesión de trabajo de 40 mensajes lo transmite 40 veces: 160.000 tokens de entrada en una sesión que son tu archivo de memoria, no tu código ni tu conversación. Trabaja cinco sesiones al día y estás moviendo 800.000 tokens de CLAUDE.md diarios. En un mes de 22 días, unos 17,6 millones.
El caché de prompts rescata la mayor parte del coste en dólares, y hay que ser honestos con eso. La entrada cacheada en Sonnet cuesta una décima parte del precio base, así que esos 17,6M de tokens cuestan un par de dólares al mes si el caché se mantiene caliente, más bien 50 $ si no. Molesto, no ruinoso.
El coste que el caché no rescata es el contexto. La ventana de contexto de Claude Code es finita, y las sesiones largas ya terminan en compactación, donde la conversación se resume y el detalle se pierde. Un residente permanente de 4.000 tokens significa que llegas antes a la compactación, en cada sesión, para siempre. También degrada la atención antes de tocar ningún límite duro: está demostrado que los modelos siguen mejor las instrucciones cuantas menos compiten entre sí. La diferencia entre un archivo de 500 tokens y uno de 4.000 no son 3.500 tokens. Es si al modelo todavía le importa tu regla de "nunca toques staging" en el mensaje 35.
Haz los mismos números con el ejemplo recortado de arriba: 500 tokens, 40 mensajes, cinco sesiones, 22 días. Unos 2,2M de tokens al mes, una octava parte de la versión hinchada, con las reglas importantes de pie en una sala despejada. El playbook completo de recorte de costes lo escribimos en nuestra guía de costes de tokens, y recortar CLAUDE.md es sistemáticamente la victoria más barata que contiene.
Proyecto vs global: la división de ~/.claude/CLAUDE.md
Tienes dos archivos, y las cosas se tuercen cuando el contenido cae en el equivocado.
~/.claude/CLAUDE.md es global. Se carga en todos los proyectos, así que solo debe contener cosas ciertas en todas partes: "uso pnpm en todos mis proyectos personales", "responde en inglés aunque mis prompts a veces estén en ruso", "nunca hagas commit sin que te lo pida". Mantenlo por debajo de diez líneas. Cada línea de aquí se multiplica por todo tu trabajo, así que su presupuesto debe ser el más estricto.
<project>/CLAUDE.md es el archivo de proyecto, versionado en git, compartido con compañeros y con la CI. Hechos sobre este codebase, con la forma del ejemplo de arriba. Como es compartido, las preferencias personales no pintan nada en él; para eso están CLAUDE.local.md o el archivo global.
Los CLAUDE.md de subdirectorio son el nivel intermedio infrautilizado. Un packages/api/CLAUDE.md con hechos específicos de la API se carga solo cuando Claude toca ese paquete. Si el archivo raíz de tu monorepo tiene secciones que aplican a un solo workspace, bajarlas un nivel es ahorro de tokens gratis sin pérdida de información.
Una idea errónea que conviene matar: poner algo en más de uno de estos archivos no hace que Claude lo siga con más fuerza. Hace el archivo más largo. Elige un hogar por hecho.
Mantenerlo fresco
CLAUDE.md se pudre más rápido que la documentación normal porque nada se rompe de forma visible cuando está mal. Los tests fallan haciendo ruido. Un archivo de memoria caducado simplemente desorienta al modelo en silencio, el modelo se recupera en silencio, y tú pagas por ambas cosas en silencio.
Nuestro ritual es aburrido y lleva diez minutos al mes. Abre el archivo. Para cada comando, ejecútalo de verdad. Para cada hecho declarado, pregúntate si sigue siendo cierto y si Claude se equivocó en algo este mes por su culpa. Borra al menos una línea; siempre hay una línea, y si no la encuentras, tus estándares de "ganarse el sitio" se han relajado. Luego revisa la longitud: una pantalla es el objetivo, dos pantallas el techo, y pasado eso ya no estás editando, estás extrayendo a skills.
El mejor disparador para actualizar no es el calendario, de todos modos. Es el momento en que Claude hace algo mal porque el archivo lo engañó. Arregla el archivo en el mismo gesto que el código. Trata los bugs de CLAUDE.md como bugs, porque tienen el mismo comportamiento de recurrencia: sin arreglar, vuelven a pasar en la siguiente sesión.
PACK SKILLPROOF
El Optimizer Pack es nuestro bundle testeado para exactamente este problema: skills que auditan tu gasto de contexto, adelgazan tu configuración y mantienen las sesiones rápidas. Cada skill que incluye pasó nuestras pruebas en máquina limpia, y el pack se paga solo en el primer mes de tokens ahorrados.
Consigue el Optimizer Pack — 10 $FAQ
¿Cuánto debería ocupar un CLAUDE.md?
Menos de 500 palabras para la mayoría de proyectos, menos de 1.000 para un monorepo genuinamente complicado. Nuestro test de trabajo: si no cabe en una pantalla, algo de lo que contiene es comportamiento disfrazado de hecho, y ese algo pertenece a un skill. El ejemplo de este artículo tiene unas 350 palabras y cubre una app mediana real.
¿Cuál es la diferencia entre CLAUDE.md y un skill?
El comportamiento de carga. CLAUDE.md se carga entero, siempre, para cada petición. Un skill expone solo una descripción de una línea hasta que una tarea encaja con él, y entonces se carga bajo demanda. Así que CLAUDE.md debería contener hechos que necesitas constantemente, y los skills, procedimientos que necesitas de vez en cuando. Nuestra guía de skills cubre la mecánica.
¿Debería subir CLAUDE.md a git?
Sí. Es documentación compartida, y las sesiones de Claude de tus compañeros se benefician de los mismos hechos que las tuyas. Guarda las preferencias personales en CLAUDE.local.md (en el gitignore) o en tu archivo global en lugar de imponérselas al equipo.
¿Puedo usar archivos CLAUDE.md anidados en subdirectorios?
Sí, y en monorepos deberías. Claude Code carga el archivo de un subdirectorio cuando trabaja con archivos de ahí. El archivo raíz recibe los hechos de todo el repo, packages/api/CLAUDE.md recibe los de la API, y los proyectos de un solo paquete pueden saltarse el anidamiento por completo.
¿Recortar CLAUDE.md cambia realmente el comportamiento de Claude, o solo el coste?
Ambos, y el comportamiento es la victoria mayor. El seguimiento de instrucciones se degrada a medida que crece su número; un archivo corto con cinco reglas afiladas se obedece con más fiabilidad que uno largo con treinta. El ahorro de tokens es la parte medible, y nuestro ranking de eficiencia rastrea qué skills ayudan más ahí, pero la mejora de cumplimiento es lo que notarás primero.
Una última opinión: los mejores archivos CLAUDE.md que hemos visto se editaron todos a base de borrar. Nadie escribe uno excelente el primer día. Escribes uno mediocre, observas dónde tropieza Claude, añades el hecho que lo habría evitado y recortas una línea de relleno para pagarlo. Seis semanas de eso ganan a cualquier plantilla, incluida la nuestra.
★ 9.6/10 × 3
El pack de inicio gratis
Los 3 skills con nuestras mejores puntuaciones de test más la checklist de instalación: el setup que pondríamos en una máquina recién estrenada. Gratis, por email.