Si ton projet Next.js commence à te bouffer 20, 40, 60 Go sur le SSD, ce n’est pas un “mystère de Node”. Dans 90% des cas, c’est juste toi qui as laissé des caches grossir sans garde-fous. Et comme ça “marche” (jusqu’au jour où ça ne marche plus), personne ne met les mains dedans.
On va parler concret : ce qu’il y a vraiment dans .next et .turbo, pourquoi ça peut partir en vrille, comment trouver le dossier coupable en 10 minutes, puis comment nettoyer et surtout empêcher que ça revienne. Avec un point très important au passage : oui, tout supprimer marche… mais tu peux aussi nettoyer intelligemment pour éviter de te reprendre une recompil interminable.
Ce qu’il y a vraiment dans .next et .turbo (et pourquoi ça peut grossir très vite)
.next, c’est le répertoire de travail de Next.js. Tu y retrouves des artefacts de build et de dev, des sorties serveur/client, et surtout des caches internes. Selon ta version et ton bundler (Webpack ou Turbopack), l’organisation varie, mais le pattern est stable : Next garde des choses pour éviter de tout recalculer à chaque relance. Et en dev, il peut garder beaucoup.
Le coupable classique dans .next, c’est .next/cache. C’est là que tu vois des caches de compilation (SWC, bundler), des métadonnées, et tout ce qui rend les rebuilds plus rapides. Sur un projet “normal”, ça reste raisonnable. Sur un monorepo, un design system lourd, des imports qui changent tout le temps, des générations de code, ou des assets nombreux, ça peut gonfler sans que tu t’en rendes compte. Et sur Mac, avec des milliers de petits fichiers, tu peux en plus avoir une sensation de “ça explose” parce que l’overhead filesystem s’ajoute.
.turbo, c’est un autre monde. C’est typiquement le cache local de Turborepo (le runner de tâches). Il stocke des résultats de tâches “cacheables” pour éviter de relancer des builds/tests/lints quand les inputs n’ont pas changé. Le truc, c’est que si tu caches des outputs volumineux (ou trop nombreux), ou si ta config d’outputs est trop large, tu peux te fabriquer une décharge sans le vouloir. Et contrairement à un cache HTTP, personne ne vient “faire le ménage” à ta place avec une politique de rétention qui colle à ton usage.
Quand tu cumules Next + monorepo + Turborepo + Turbopack activé en dev (par exemple via next dev --turbo selon ton setup), tu peux donc avoir deux systèmes qui “optimisent” chacun dans leur coin. Résultat : ça va vite, jusqu’au jour où le disque dit non.
Sponsorisé par Le Scribouillard
Besoin de contenu optimisé SEO ?
Utilisez la meilleure plateforme française de création de contenu assistée par IA ! Et générez des articles pour moins de 1€ !
Diagnostiquer en 10 minutes : trouver le vrai dossier qui te flingue le SSD
Le piège, c’est de faire un rm -rf .next .turbo en panique et de s’arrêter là. Tu viens de gagner de la place, mais tu n’as rien compris, donc ça reviendra. Ce que tu veux, c’est identifier quel sous-dossier grossit et à quel rythme. Parce que “50 Go de cache”, ça n’a pas du tout la même cause si c’est 50 Go de .turbo (mauvais outputs) ou 50 Go de .next/cache (rebuilds qui churnent à mort).
Sur macOS et Linux, le plus rentable c’est juste un du en profondeur faible, puis tu descends dans le dossier coupable. Si tu es visuel, ncdu te fait gagner un temps indécent.
# À lancer à la racine du repo
du -sh .next .turbo 2>/dev/null
# Top des sous-dossiers (ajuste la profondeur)
du -h -d 2 .next .turbo 2>/dev/null | sort -h | tail -n 30
# Si tu suspectes quelques énormes fichiers
find .next .turbo -type f -size +200M -print 2>/dev/nullSur Windows, tu peux faire la même idée en PowerShell, mais je vais être honnête : si tu es dans un gros monorepo, installe un outil de visualisation (WinDirStat, WizTree) et tu vas comprendre en 30 secondes ce qui prend de la place.
Ce que je cherche immédiatement : un .next/cache qui fait plusieurs gigas, un .turbo qui contient des caches par milliers, ou des dossiers d’outputs qui n’auraient jamais dû être “cacheés” (typiquement des builds entiers, des bundles dupliqués, ou des sorties générées trop lourdes). Si je vois un pattern où le poids augmente à chaque next dev sans redescendre, je sais que je dois mettre une politique de nettoyage, pas juste un one-shot.
Nettoyer sans regret : ce que tu peux supprimer, et ce que j’évite de toucher
On va être clair : supprimer .next et .turbo ne va pas “casser” ton projet. Ça va juste te coûter du temps au prochain démarrage, parce que tu supprimes des caches et des artefacts que les outils vont reconstruire.
Le nettoyage le plus sûr, le plus boring, c’est de supprimer .turbo (cache local Turborepo) et .next/cache (cache de compilation), plutôt que de raser toute la sortie .next si tu veux limiter la douleur. Dans beaucoup de cas, .next/cache est la partie qui gonfle et qui, une fois purgée, règle le problème sans te remettre à zéro sur tout.
Là où je fais attention : si ton environnement dépend d’artefacts précis dans .next (rare en dev pur, plus fréquent sur des scripts maison), un rm -rf .next peut provoquer des comportements bizarres jusqu’au prochain build complet. Ce n’est pas “dangereux”, mais ça peut te faire perdre 20 minutes à te demander pourquoi tel endpoint renvoie n’importe quoi. Donc mon réflexe : je commence par .next/cache, et je n’efface .next entier que si j’ai un build vraiment incohérent.
Et oui, ça vaut le coup d’avoir un script “clean” dans le repo. Pas pour faire joli. Pour éviter que chaque dev réinvente son rm -rf avec des variantes foireuses.
#!/usr/bin/env bash
set -euo pipefail
# clean-next-turbo.sh
# Objectif : récupérer du disque sans repartir complètement de zéro.
echo "[clean] sizes before"
du -sh .next .turbo 2>/dev/null || true
echo "[clean] removing Turborepo cache (.turbo)"
rm -rf .turbo
echo "[clean] removing Next.js compile cache (.next/cache)"
rm -rf .next/cache
# Optionnel : si tu sais que ton projet accumule des artefacts en dev
# rm -rf .next
echo "[clean] sizes after"
du -sh .next .turbo 2>/dev/null || true
echo "[clean] done"Tu peux le brancher sur un npm run clean ou pnpm clean. Et si tu as des devs qui n’aiment pas le terminal, un bouton “Clean caches” dans le README, ça évite des drames silencieux.
Pourquoi ça revient : rebuilds en boucle, outputs trop larges, et “cache partout” par défaut
Quand je vois un cache qui monte à 50 Go, ce n’est presque jamais “juste Next”. Il y a souvent un pattern derrière.
Premier pattern : le rebuild qui churn. Un watcher qui retrigger trop souvent (génération de fichiers, formatteur qui réécrit, codegen qui touche des timestamps, script qui sync des assets) peut faire produire des artefacts en continu. Tu ne le vois pas forcément à l’œil, mais tu le vois au disque. Si à chaque sauvegarde un paquet de fichiers est régénéré, tes outils recompilent, recachent, et ton “gain de perf” devient une usine.
Deuxième pattern : la config Turborepo qui cache trop large. Dans Turborepo, la notion d’outputs est centrale. Si tu déclares des outputs énormes pour une tâche (ou si tu inclus des dossiers qui bougent beaucoup), tu vas mettre au cache des choses qui n’ont pas de valeur. Pire : tu vas les dupliquer dans le cache au fil des runs, parce que le hash change. C’est comme versionner des builds : tu peux, mais tu vas le payer.
Troisième pattern : la CI qui restaure des caches et en repousse des nouveaux sans jamais “couper” proprement. En local, tu souffres du SSD. En CI, tu souffres du temps de restore/save, et parfois tu dépasses des limites de taille. Le cache devient alors une taxe, pas une optimisation.
CI : cacher oui, mais seulement ce qui a un ROI (et avec des clés saines)
Le réflexe “je cache tout le dossier .next” est souvent une mauvaise idée. Déjà parce que tu caches aussi des sorties qui ne devraient pas voyager entre runs. Ensuite parce que tu as plus de risques d’incohérences subtiles. Dans pas mal de setups, ce qui vaut le coup de cacher, c’est plutôt .next/cache (pour accélérer le build) et le cache Turbo si tu l’utilises vraiment pour accélérer des tâches répétées.
Le point clé, c’est la clé de cache. Si tu ne fais varier ta clé que sur l’OS, tu vas réutiliser des caches qui n’ont rien à voir avec ton code actuel. Si tu la fais varier sur le lockfile mais pas sur ta config Next/Turbo, tu vas te traîner des surprises quand tu changes un paramètre de build. Tu veux une clé qui bouge quand les entrées “structurantes” bougent, pas à chaque commit, et pas jamais.
# Exemple GitHub Actions (adaptable GitLab/Circle/etc. sur le même principe)
# Objectif : accélérer sans transformer le cache en décharge.
- name: Cache Next.js + Turbo
uses: actions/cache@v4
with:
path: |
.next/cache
.turbo
key: ${{ runner.os }}-next-turbo-${{ hashFiles('**/pnpm-lock.yaml', '**/package-lock.json', '**/yarn.lock', 'turbo.json', 'next.config.*') }}
restore-keys: |
${{ runner.os }}-next-turbo-
Mon avis terrain : si ton .turbo devient un monstre, le bon move en CI n’est pas forcément de “mieux le cacher”, c’est parfois de basculer sur du remote cache bien géré (ou de réduire l’ambition de ce que tu caches). Le cache local compressé/uploadé/downloadé sur chaque run peut finir plus lent que de reconstruire proprement, surtout si tu as beaucoup de petits fichiers.
Quand désactiver Turbopack temporairement (oui, ça se défend)
Je sais, on veut tous le tooling moderne. Mais quand un outil te fait perdre du temps en friction (disque, instabilités, comportements non reproductibles), il faut savoir revenir à une config boring le temps de stabiliser.
Si tu as activé Turbopack explicitement (souvent via next dev --turbo, ou via un script dev), teste une semaine sans. Reviens au bundler “classique” de ton setup, mesure le temps de startup, le temps de rebuild, et surveille le disque. Ce test-là te dit quelque chose de simple : est-ce que tu es face à un problème d’accumulation spécifique à Turbopack, ou est-ce que ton projet a un problème structurel de churn qui ferait exploser n’importe quel cache ?
Et si tu es en monorepo, ne sous-estime pas une cause bête : des symlinks, des packages liés en workspace, des dossiers buildés qui se réinjectent dans l’arbre surveillé. Un bundler qui watch “trop large” + un codegen bavard = une machine à recacher.
Bonus : faire un “clean” sans perdre 2h à tout recompiler
Le gros nettoyage rm -rf .next est cathartique, mais il peut transformer la reprise en enfer sur un gros projet. Quand je veux récupérer de la place sans tout payer derrière, j’attaque en escalier.
D’abord, je supprime .turbo. Ça remet à zéro le cache de tâches, mais ça n’oblige pas Next à tout reconstruire côté bundler. Ensuite, je vise .next/cache si c’est lui qui a gonflé. C’est souvent suffisant pour reprendre un état sain. Et seulement si j’ai des symptômes de build incohérent, ou un dossier .next qui contient des artefacts manifestement aberrants, je supprime tout .next.
Le truc qui fait gagner du temps ensuite, c’est d’éviter le “premier build” au pire moment. Si tu viens de faire un clean et que tu sais que tu vas ouvrir 3 apps du monorepo, lance un build ou un dev server à un moment où tu n’es pas pressé, laisse-le reconstruire, puis reprends ton flow. Ça a l’air idiot écrit comme ça, mais ça évite le classique “j’ai nettoyé, j’ai une réunion, et maintenant rien ne démarre”.
Mon arbitrage : un cache doit être un accélérateur, pas un risque opérationnel
La phrase à garder en tête est simple : si ton cache n’a pas de limites, ce n’est pas un cache, c’est une dette. En local ça finit en SSD plein, en CI ça finit en minutes perdues, et dans les deux cas tu gagnes une optimisation “théorique” contre des emmerdes bien réelles.
Donc oui, nettoie. Mais surtout, rends le nettoyage normal. Un script dans le repo. Une habitude quand le cache dépasse un seuil. Une CI qui cache ce qui a un vrai ROI, avec des clés propres. Et si tu dois couper une option moderne (Turbopack) une semaine pour retrouver un environnement stable, fais-le sans culpabiliser. Le but, c’est de livrer, pas de collectionner des gigas de fichiers temporaires.