CLAUDE.md : le guide complet avec exemples Django, Node et Next.js
Comment écrire un CLAUDE.md efficace pour Claude Code : hiérarchie, bonnes pratiques, anti-patterns et trois exemples détaillés Django, NestJS et Next.js.
Le Briefing Dev - les ressources et actus de la semaine, droit dans ta boîte chaque vendredi gratuitement.
Si vous utilisez Claude Code et que vous corrigez la même chose à chaque session, c'est que votre projet n'a pas de CLAUDE.md, ou que celui que vous avez écrit n'est pas le bon. Ce fichier est probablement le levier au meilleur retour sur investissement de tout l'écosystème Claude Code. Une heure passée à le rédiger correctement vous fait gagner des dizaines d'heures de corrections répétées. Voici comment l'écrire pour de vrai, avec des exemples ligne par ligne sur trois stacks classiques.
Ce qu'est CLAUDE.md, et ce qu'il n'est pas
CLAUDE.md est un fichier Markdown que Claude Code charge automatiquement au début de chaque session. Son contenu est injecté dans le prompt système avant votre premier message. Tout ce qui s'y trouve devient une instruction permanente que Claude essaie de suivre tout au long de la conversation.
L'analogie la plus juste : une note de briefing pour un nouveau collègue qui perdrait la mémoire entre chaque journée. Il connaît son métier, mais pas votre projet. CLAUDE.md lui transmet ce qu'un humain mettrait deux jours à apprendre par observation : votre stack, vos commandes, vos conventions, vos pièges. Sans ce fichier, vous ré-expliquez la même chose à chaque session. Avec, Claude attaque le travail avec le bon contexte dès la première instruction.
Important : CLAUDE.md n'est pas une configuration au sens strict. Claude le traite comme du contexte, pas comme une règle absolue. Des instructions claires, courtes et vérifiables sont mieux suivies que des paragraphes vagues. Au-delà de 200 ou 300 lignes, l'adhérence diminue, et chaque ligne consomme de la fenêtre de contexte à chaque tour.
La hiérarchie : où placer le fichier
Claude Code charge plusieurs CLAUDE.md selon une hiérarchie qui va du plus général au plus spécifique. Comprendre cette hiérarchie évite des heures de confusion quand un comportement bizarre apparaît.
Au plus haut, les politiques managées (enterprise) imposées par l'organisation. En dessous, votre fichier global personnel dans ~/.claude/CLAUDE.md qui s'applique à tous vos projets. Puis le CLAUDE.md à la racine du projet, versionné dans Git, avec les conventions partagées. Encore en dessous, les CLAUDE.md placés dans des sous-répertoires, qui ne se chargent que quand Claude travaille dedans. Enfin, CLAUDE.local.md que vous gardez pour vous (dans .gitignore) avec vos préférences personnelles.
La règle de précédence est simple : le plus spécifique l'emporte. Si le CLAUDE.md d'un sous-répertoire dit « 2 espaces » et celui de la racine dit « 4 espaces », c'est le 2 qui gagne quand Claude travaille dans ce sous-répertoire. La commande /memory liste tous les fichiers actifs.
Ce qu'on met dedans, ce qu'on laisse dehors
Le piège classique, c'est de tout y mettre. La doc complète de l'API, les paragraphes sur l'historique du projet, la philosophie. Erreur. Chaque ligne paye un coût en tokens à chaque tour, et plus le fichier est long, moins Claude suit ses instructions.
Ce qui mérite sa place : les commandes shell quotidiennes (make test, pnpm dev), les choix d'architecture qui guident où poser quoi, les fichiers centraux à connaître, les règles non négociables (sécurité, RGPD, déploiements en deux temps), et les anti-patterns que vous avez payés cher.
Ce qui ne mérite pas sa place : les règles de formatage automatique (laissez Prettier, ESLint, ruff faire), la doc détaillée d'une API (mettez-la en fichier séparé), les explications historiques, les évidences déductibles du package.json ou du pyproject.toml.
La règle qui marche : si vous voulez que Claude le sache dans six mois, ça va dans CLAUDE.md. Si ça peut changer la semaine prochaine, ça reste dans vos prompts.
Repère pratique. Visez moins de 100 lignes pour la plupart des projets. Un CLAUDE.md de 50 lignes consomme environ 2000 tokens, soit moins de 1% de la fenêtre de contexte d'Opus 4.7. Si vous dépassez 200 lignes, c'est probablement le signe qu'il faut découper en fichiers de règles modulaires dans .claude/rules/.
Exemple 1 : un projet Django + DRF
Plongeons dans le concret. Voici un CLAUDE.md complet pour un projet Django avec une API REST DRF, suivi du commentaire de chaque section.
# Project: LaPolaris API
API REST de gestion des cours et inscriptions. Django 5.0, Python 3.12, PostgreSQL 16.
## Commandes
- `make dev` : runserver + worker celery + redis
- `make test` : pytest avec couverture (cible: 85%)
- `make test-fast` : tests unitaires sans la DB
- `make lint` : ruff + mypy
- `make migrate` : applique les migrations
- `make shell` : django-shell-plus avec ipython
## Architecture
- `apps/<domaine>/` : une app par domaine métier (courses, enrollments, billing, users)
- `apps/<domaine>/services.py` : logique métier réutilisable, testable sans DB
- `api/v1/` : endpoints DRF, jamais de requête ORM directe ici
- `core/` : helpers, exceptions, base classes (pas de logique métier dedans)
- `config/settings/` : base.py, dev.py, prod.py
## Conventions
- Type hints obligatoires sur tout code public
- Pas d'ORM dans les vues : passer par `apps/<domaine>/services.py`
- Tests : pytest-django + factory_boy, jamais `setUp()` style unittest
- Import order : stdlib, tiers, locaux (ruff s'en charge)
## Règles non négociables
- Ne jamais committer sans `make test` et `make lint` au vert
- Toute migration doit être réversible (tester `migrate <app> <previous>`)
- Les secrets vont dans `.env`, jamais dans le code
- Webhooks Stripe : toujours vérifier la signature avant traitement
- RGPD : pas d'email en clair dans les logs, utiliser `core.privacy.mask_email()`
## Anti-patterns à éviter
- `User.objects.get()` sans try/except : utiliser `get_object_or_404` ou un service
- Migration data + migration de schéma dans le même fichier : les séparer
- Imports circulaires entre apps : passer par les signals ou le dispatch
## Outils MCP disponibles
- `stripe-test` : exploration des paiements en mode test
- `postgres-readonly` : analyses ad-hoc, lecture seule uniquement
Décortiquons. La première ligne donne le titre et un résumé d'une phrase. Pas de paragraphe d'introduction, pas d'historique. Claude a besoin de savoir ce que fait le projet en cinq secondes.
La section Commandes est la plus rentable. Vous donnez les chaînes exactes que vous tapez tous les jours, Claude les utilise verbatim. Si votre commande de test est make test et pas pytest, dites-le. Sinon Claude tombera sur la mauvaise commande à la première occasion.
La section Architecture sert de boussole. Quand Claude doit ajouter du code, il faut qu'il sache où le poser. La règle « pas de requête ORM dans api/v1/, tout passe par les services » est un choix qui se paye plusieurs fois par jour si on l'oublie. Exactement le genre de règle qui justifie sa place dans CLAUDE.md.
La section Règles non négociables est celle qui apporte le plus de valeur sur du sensible. Sécurité, RGPD, migrations en prod : ce sont des règles qui se payent cher quand elles sautent. Les écrire en majuscules n'aide pas, par contre les formuler de façon claire et active aide énormément.
La section Anti-patterns est l'arme cachée. Vous y mettez les erreurs récurrentes observées. Claude est doué, mais il a des biais. Si vous voyez qu'il fait toujours la même bêtise sur un point précis, cette section est faite pour ça.
Pour creuser ces conventions Django et l'organisation par services, le concept est détaillé dans mes contenus de formation backend Python.
Exemple 2 : une API NestJS
Changement de stack, mais la philosophie reste la même. Voici l'équivalent pour une API Node tournant sous NestJS, avec Prisma comme ORM.
# Project: Sentinel API
API NestJS de monitoring d'applications. Node 20, TypeScript strict, Prisma + PostgreSQL.
## Commandes
- `pnpm dev` : démarre l'API en mode watch
- `pnpm test` : Jest unit + integration
- `pnpm test:e2e` : tests end-to-end avec base dédiée
- `pnpm lint` : eslint + prettier --check
- `pnpm db:migrate` : `prisma migrate dev`
- `pnpm db:reset` : reset + seed (DEV ONLY)
## Architecture
- `src/modules/<domaine>/` : modules NestJS isolés (alerts, users, projects)
- Chaque module : `<module>.controller.ts`, `<module>.service.ts`, `<module>.module.ts`
- DTO d'entrée et de sortie séparés, validés via class-validator
- `src/common/` : guards, interceptors, filters partagés
- `prisma/schema.prisma` : source de vérité pour le schéma
## Conventions
- TypeScript strict : pas de `any`, pas de `as` non justifié
- Pas de `default export`, sauf pour les modules NestJS
- Async/await partout, jamais de `.then()` chaîné
- Logs : `Logger` de NestJS, jamais `console.log` en prod
## Règles non négociables
- Toute route protégée par défaut : auth opt-out explicite via décorateur `@Public()`
- Validation DTO obligatoire sur tout input externe
- Jamais de Prisma client en dehors d'un service
- Ne pas modifier les migrations déjà déployées : créer une nouvelle migration
## Tests
- Un test par cas métier, pas un test par fonction
- Mocks Prisma via `jest-mock-extended`, pas de vraie DB en unit
- Les tests e2e tournent contre une base dédiée nettoyée entre chaque suite
## Anti-patterns
- Service qui appelle un autre Controller : remonter la logique dans un service partagé
- Try/catch silencieux : toujours logger ou re-throw
- `findOne()` sans gestion du `null` : utiliser `findOneOrThrow()` ou un guard
Plusieurs choses à noter. La section Commandes mentionne explicitement pnpm. Si votre projet utilise pnpm et pas npm, dites-le, sinon Claude tombera sur npm par défaut. Détail typique qu'on ne pense pas à signaler et qui fait perdre du temps à chaque session.
La section Architecture décrit la structure d'un module NestJS. Donner ce squelette une fois évite à Claude de réinventer une organisation différente à chaque nouveau module. Le détail « DTO d'entrée et de sortie séparés » est une convention forte à appliquer partout.
Les règles non négociables sont l'endroit pour vos décisions de sécurité par défaut. « Toute route protégée par défaut » est un choix qui change tout sur l'API publique. Le mentionner explicitement évite que Claude crée une route exposée par mégarde.
La section Tests est importante : les approches varient énormément d'une équipe à l'autre. Préciser « mocks Prisma via jest-mock-extended » fait gagner un temps fou. Sinon Claude propose de mocker à la main, ce qui marche, mais ce n'est pas votre standard.
Exemple 3 : une application Next.js
Le front a ses propres pièges. Voici un CLAUDE.md pour une app Next.js 15 avec App Router, Tailwind, et Server Actions.
# Project: Atlas Dashboard
Dashboard Next.js 15 (App Router). React 19, TypeScript, Tailwind 4, shadcn/ui.
Backend séparé : api.atlas.io (NestJS).
## Commandes
- `pnpm dev` : Next dev avec turbopack
- `pnpm build` : build de prod (vérifie aussi les types)
- `pnpm test` : Vitest
- `pnpm test:e2e` : Playwright
- `pnpm lint` : eslint + tsc --noEmit
## Architecture
- `app/` : routes (App Router uniquement, pas de Pages Router)
- `app/(auth)/` et `app/(dashboard)/` : route groups pour les layouts
- `components/ui/` : composants shadcn générés (ne pas modifier directement)
- `components/<feature>/` : composants métier groupés par feature
- `lib/api/` : client typé pour appeler api.atlas.io
- `lib/utils.ts` : fonctions utilitaires partagées
## Conventions React
- Composants serveur par défaut, `'use client'` seulement quand nécessaire
- Pas de fetch dans les composants serveur : passer par `lib/api/`
- Server Actions pour les mutations, jamais d'API route maison
- Tailwind uniquement, pas de CSS-in-JS, pas de fichier .css par composant
- Class names via `cn()` de `lib/utils.ts`
## Conventions TypeScript
- TypeScript strict, aucun `any` toléré
- Types des réponses API dans `lib/api/types.ts`, générés depuis le swagger backend
- Props : interfaces nommées, pas de types inline
## Règles non négociables
- Pas de données sensibles dans les composants client (vérifier avec `'use server'` ou un Server Component)
- Toute Server Action utilise le wrapper `withAuth()` sauf cas explicite
- Images via `next/image`, jamais de `<img>` brut
- Liens internes via `next/link`, jamais de `<a>` brut
## Performance
- Lazy load les composants lourds : `dynamic()` avec `ssr: false` si client-only
- Cache des fetch via les options Next : `revalidate`, `tags`
- Pas de waterfall : utiliser `Promise.all` pour les fetch parallèles
## Anti-patterns
- `useState` pour de la donnée serveur : utiliser un Server Component
- `useEffect` pour fetcher : presque jamais nécessaire en App Router
- `getServerSideProps` ou `getStaticProps` : on est en App Router, ces APIs n'existent plus
Le front Next.js 2026 est un terrain miné parce que la doc et les exemples mélangent App Router et Pages Router, deux paradigmes très différents. La section Conventions React tranche dès le départ : App Router uniquement, composants serveur par défaut. Précision qui évite que Claude propose du code Pages Router qui ne tournera jamais.
La règle « pas de fetch dans les composants serveur, passer par lib/api/ » peut sembler bizarre si on ne connaît pas le projet. Justement : c'est exactement ce que CLAUDE.md doit transmettre. Les choix non évidents qui structurent le code.
La section Performance liste trois patterns simples qui couvrent 80% des cas d'optimisation Next. Plus efficace qu'un long laïus. Et la section Anti-patterns est cruciale : Next.js a une dette d'API énorme entre versions, et beaucoup de tutoriels en ligne montrent encore du getServerSideProps. Préciser que ces APIs n'existent plus protège contre les suggestions périmées.
Pour aller plus loin sur les patterns React modernes, j'aborde plusieurs de ces sujets dans le blog LaPolaris, notamment sur l'organisation des projets fullstack.
Les anti-patterns du CLAUDE.md lui-même
Au-delà du contenu, il y a des erreurs structurelles qu'on retrouve souvent quand on regarde des CLAUDE.md d'équipes. Les éviter fait toute la différence entre un fichier qui sert et un fichier qui pollue le contexte.
Le fichier-roman. 400 lignes de prose qui décrivent l'historique du projet, la philosophie, les inspirations. Tout ça est passionnant pour un humain. Pour Claude, c'est du bruit. Visez la concision, restez sous les 100 lignes, utilisez des listes plutôt que des paragraphes.
Les instructions contradictoires. Une section dit « utiliser des semicolons », une autre dit « pas de semicolons ». Ça arrive plus souvent qu'on croit. Claude choisit alors plus ou moins au hasard. Auditez votre fichier régulièrement.
Les règles passives. « Bien penser à tester avant de pusher ». C'est une intention. La version active : « Ne jamais committer sans make test au vert ». Les instructions vérifiables et impératives sont mieux suivies.
Les règles de formatage que les outils gèrent déjà. Si vous avez Prettier, ESLint, ruff, mettez vos règles dans leur configuration, pas dans CLAUDE.md.
Les évidences déductibles. « Ce projet utilise React. » Claude le voit dans le package.json. Économisez vos lignes pour ce qui n'est pas évident.
Le copier-coller de la doc officielle. Si une convention vient directement de la doc Django ou Next.js, Claude la connaît déjà. Concentrez-vous sur ce qui est spécifique à votre projet.
Découper avec .claude/rules/
Quand votre CLAUDE.md commence à dépasser 150 lignes malgré vos efforts, le bon réflexe est de découper. Les versions récentes de Claude Code supportent un dossier .claude/rules/ qui contient des fichiers de règles modulaires, chargés selon des patterns de chemins.
Vous gardez un CLAUDE.md court qui sert d'index, et vous mettez les règles spécifiques dans des fichiers comme .claude/rules/frontend.md (chargé pour app/**/*.tsx) ou .claude/rules/api.md (chargé pour api/**/*.ts). Les règles ne sont alors injectées que quand Claude touche aux fichiers concernés. Sur un monorepo fullstack, ça change tout.
Workflow : du # au CLAUDE.md
Comment alimenter votre CLAUDE.md sans y passer une journée d'un coup ? La méthode qui marche, c'est l'incrémental. Pendant vos sessions, dès que vous corrigez Claude sur la même erreur deux fois, tapez # suivi de la règle. Claude la mémorise et propose de l'ajouter au fichier de mémoire de votre choix.
Au bout de quelques semaines, votre CLAUDE.md s'enrichit de règles qui correspondent vraiment aux frictions que vous vivez, plutôt que de règles théoriques que vous auriez écrites sans contexte. C'est aussi pour ça qu'il faut commencer petit. Un fichier de 30 lignes solides vaut mieux qu'un fichier de 200 lignes spéculatives.
Enfin, n'oubliez pas l'auto-mémoire. À partir de Claude Code 2.1.59, l'outil maintient un fichier MEMORY.md où il note tout seul vos préférences observées au fil des sessions. CLAUDE.md contient ce que vous voulez, MEMORY.md contient ce que Claude a remarqué. Les deux se complètent et chargent au début de chaque conversation.
FAQ
Faut-il versionner CLAUDE.md dans Git ?
Oui, le CLAUDE.md à la racine du projet est conçu pour être partagé avec l'équipe et donc versionné. Tout le monde bénéficie ainsi des mêmes conventions. En revanche, CLAUDE.local.md (pour vos préférences personnelles) doit être ajouté à .gitignore. C'est l'endroit pour vos raccourcis et alias qui n'ont pas à devenir la norme de l'équipe.
Quelle longueur idéale pour CLAUDE.md ?
Entre 30 et 100 lignes pour la plupart des projets. Au-delà de 200 lignes, l'adhérence de Claude aux instructions diminue, et le coût en tokens devient significatif sur les longues sessions. Si vous dépassez, découpez en fichiers de règles dans .claude/rules/ avec des patterns de chemins, plutôt que d'allonger encore.
Claude suit-il vraiment toutes les instructions de CLAUDE.md ?
Non, et c'est important de le comprendre. CLAUDE.md est traité comme du contexte, pas comme une configuration stricte. Les instructions courtes, spécifiques et vérifiables sont mieux suivies que les paragraphes longs et vagues. Si une règle est régulièrement ignorée, c'est généralement le signe qu'elle est mal formulée, ou qu'elle entre en conflit avec une autre règle. Pour du déterministe, utilisez les hooks ou les permissions, pas le CLAUDE.md.
Comment générer un CLAUDE.md de départ ?
La commande /init dans Claude Code génère un fichier de départ basé sur la structure de votre projet. Attention : par défaut elle inclut beaucoup de choses évidentes (« ce projet utilise TypeScript ») qu'il vaut mieux supprimer. Considérez le résultat de /init comme un brouillon à élaguer agressivement, pas comme un produit fini.
Comment partager CLAUDE.md entre plusieurs assistants IA ?
CLAUDE.md est spécifique à Claude Code. Si votre équipe utilise aussi Cursor ou Copilot, ces outils ne le liront pas. Une convention émergente est le fichier AGENTS.md, plus générique, lu par plusieurs outils. La pratique courante est de garder CLAUDE.md pour les règles spécifiques Claude et AGENTS.md pour les règles communes, ou simplement de symlinker l'un vers l'autre si les contenus sont identiques.
Que mettre dans le CLAUDE.md global de mon home directory ?
Le fichier ~/.claude/CLAUDE.md est lu pour tous vos projets. Réservez-le à vos préférences personnelles transversales : langue de réponse (français par exemple), style de communication souhaité, raccourcis que vous utilisez partout. Ne mettez surtout pas de règles métier ou de conventions de stack ici : elles seraient appliquées même sur des projets où elles n'ont pas de sens.
Faut-il un CLAUDE.md par sous-répertoire dans un monorepo ?
Oui, c'est même un des cas où la hiérarchie brille le plus. Sur un monorepo avec un apps/api/ Django et un apps/web/ Next.js, vous gardez un CLAUDE.md racine très court avec les commandes globales, puis un CLAUDE.md spécifique dans chaque sous-app. Quand Claude travaille dans apps/api/, il charge le CLAUDE.md backend ; quand il bascule sur apps/web/, il charge l'autre. Pas de pollution croisée.
L'auto-mémoire remplace-t-elle CLAUDE.md ?
Non, les deux sont complémentaires. CLAUDE.md contient ce que vous voulez explicitement transmettre. L'auto-mémoire (MEMORY.md) contient ce que Claude a observé sur vos préférences au fil des sessions. La bonne pratique est de laisser l'auto-mémoire active pour capturer les détails fins, et d'utiliser CLAUDE.md pour les règles structurelles que vous voulez maîtriser totalement. Vous pouvez parcourir et éditer MEMORY.md à tout moment via /memory.