La plupart des développeurs atteignent le même plafond : l'abonnement Claude à 20 $/mois couvre l'usage quotidien, mais dès que vous commencez à exécuter des audits, rédiger de la documentation et examiner des PR à grande échelle, les coûts d'API grimpent vite. La solution est une configuration hybride — laissez un agent Hugging Face auto-hébergé gérer le travail à fort volume et à faible enjeu, et gardez Claude concentré sur les tâches qui ont besoin de sa précision.
Routing Strategy
local / PikaPods
API
Hugging Face
Gère tout ce qui est répétitif, large ou exploratoire — audits, documentation, recherche, descriptions de PR — à coût nul ou quasi nul par token. Il y a deux façons de mettre ça en place : se connecter aux Inference Providers hébergés de Hugging Face via un agent de terminal appelé OpenCode, ou se passer complètement de l'inférence hébergée et faire tourner un modèle entièrement en local avec Ollama. Les deux s'intègrent dans le même flux de terminal et aucune ne change votre façon d'utiliser Git — choisissez selon que vous préférez payer quelques dollars par mois pour de l'inférence GPU hébergée, ou tout garder sur votre propre machine.
OpenCode est un agent de codage IA basé sur le terminal. Il se place entre un modèle — Hugging Face, dans cette configuration — et votre dossier de projet local, et donne à ce modèle la capacité de lire votre code, d'éditer et créer des fichiers, d'exécuter des commandes terminal, d'inspecter les erreurs et de chercher dans tous les fichiers. Il ne touche pas à Git ou GitHub directement ; votre flux git add / commit / push habituel reste exactement le même.
Option A — Inférence Hugging Face via OpenCode
C'est la configuration la plus complète : inférence hébergée, pas besoin de GPU local, intégrée dans le même terminal que vous utilisez déjà pour Claude Code, pointée vers un repo déjà synchronisé avec GitHub.
1. Créez un compte Hugging Face
Inscrivez-vous sur huggingface.co/join — vous n'avez pas besoin de créer un repo de modèle, un dataset, ou un Space. Le compte seul suffit pour générer un token ensuite.
2. Installez le CLI Hugging Face
▶ show code▼ hide code
brew install hf
hf --help
Puis connectez-vous. Le flux par navigateur est l'option la plus simple — il vous donne un code, ouvre Hugging Face, et stocke l'identifiant localement une fois que vous approuvez :
▶ show code▼ hide code
hf auth login
hf auth whoami
hf auth whoami devrait afficher votre nom d'utilisateur Hugging Face — ça confirme que la connexion a fonctionné.
3. Installez OpenCode
▶ show code▼ hide code
brew install anomalyco/tap/opencode
opencode --version
Le tap anomalyco est le tap Homebrew propre à l'équipe d'OpenCode et reçoit généralement les mises à jour plus vite que la formule miroir.
4. Créez un token d'API Hugging Face pour OpenCode
L'étape hf auth login ci-dessus authentifie le CLI hf lui-même et enregistre un identifiant interne OAuth-user — vous verrez une confirmation du type "The token OAuth-user is saved." Ce n'est pas le token qu'utilise OpenCode, même si cela ressemble à une réussite. OpenCode a besoin d'un token à granularité fine distinct, que vous créez manuellement sur huggingface.co/settings/tokens avec la permission Make calls to Inference Providers et rien d'autre. La chaîne hf_... affichée à la création est celle que vous collez lorsque le auth login d'OpenCode demande une "API key" — l'interface de Hugging Face parle de token, OpenCode parle d'API key ; c'est la même chose.
Allez sur huggingface.co/settings/tokens et créez un token fine-grained (à permissions fines). La seule permission nécessaire est :
Make calls to Inference Providers
Vous n'avez pas besoin de lui accorder de permission pour modifier votre repo GitHub — OpenCode lit et écrit vos fichiers locaux directement, et Git reste entièrement séparé de ce token.
Le token ressemblera à hf_xxxxxxxxxxxxxxxxxxxxx. Ne le collez jamais dans une fenêtre de chat, un commit, ou un fichier .env suivi par Git. Si vous le stockez dans .env.local, vérifiez que .env* est déjà dans votre .gitignore avant de l'enregistrer.
5. Connectez OpenCode à Hugging Face
▶ show code▼ hide code
opencode auth login
Choisissez Hugging Face dans la liste des fournisseurs, puis collez le token de l'étape 4 lorsqu'il demande une API key (l'invite dit "API key", pas "token"). C'est la méthode de connexion officiellement documentée entre les deux outils.
6. Pointez OpenCode vers votre repo existant
C'est la partie qui compte pour un repo déjà synchronisé avec GitHub — OpenCode ne remplace ni ne duplique jamais votre configuration Git, il opère seulement sur les fichiers déjà présents.
▶ show code▼ hide code
cd ~/chemin/vers/votre/projet/existant
git status
Vérifiez que l'arbre de travail est propre (On branch main, up to date with 'origin/main') avant de commencer, afin que les modifications d'OpenCode soient faciles à isoler ensuite avec git diff. Puis lancez l'agent depuis ce répertoire :
▶ show code▼ hide code
opencode
À partir de là, le flux est : votre modèle Hugging Face raisonne, OpenCode lit et modifie les fichiers du répertoire depuis lequel vous l'avez lancé, et Git — votre repo local existant, poussant vers le même remote GitHub — reste seul responsable du versioning et de la synchronisation. Il n'y a pas de seconde copie de l'app qui vivrait sur Hugging Face.
7. Choisissez un modèle de code
Dans OpenCode :
▶ show code▼ hide code
/models
Choisissez Hugging Face et sélectionnez parmi les modèles actuellement disponibles via Inference Providers. Cette liste change souvent — Hugging Face route les modèles pris en charge à travers plusieurs fournisseurs et peut choisir un fournisseur selon la vitesse ou le prix — donc ne codez pas en dur un modèle précis dans votre flux de travail. Privilégiez ce qui est étiqueté pour le code, dispose d'une fenêtre de contexte assez grande pour les fichiers sur lesquels vous travaillez, et correspond au compromis vitesse/coût que vous voulez pour le travail en masse.
Contrairement à Ollama, où vous téléchargez un modèle précis sur votre machine, les Inference Providers font tourner leur catalogue de modèles et peuvent choisir un fournisseur selon la vitesse ou le prix à votre place. Choisissez donc le modèle étiqueté pour le code le plus récent disponible dans le menu /models plutôt que de vous figer sur un nom cité dans un guide. Tout nom de modèle précis de cet article peut déjà être dépassé et n'être plus tout à fait à jour — prenez-le comme une suggestion de départ, pas comme une vérité absolue.
De nombreux modèles actuels des Inference Providers exposent un réglage d'effort de raisonnement — low, medium, high, xhigh ou équivalent. Le bon choix dépend de la tâche.
Choisissez medium pour le travail que vous routez vers Hugging Face. L'Option A sert aux audits, à la documentation, aux descriptions de PR et aux revues — du travail en volume où la vitesse et le coût comptent. Un raisonnement moyen suffit à repérer de vrais problèmes sans payer la latence et le coût en tokens des niveaux supérieurs. Réservez high ou xhigh aux tâches qui exigent une précision approfondie sur plusieurs fichiers — et ce sont précisément les tâches que la stratégie de routage demande de garder sur Claude, pas sur Hugging Face. Utiliser xhigh ici va à l'encontre du principe de la répartition : vous subissez la latence et le coût d'un raisonnement intensif sans obtenir la précision de Claude.
Les modèles indiqués comme variantes de réflexion ou de raisonnement — par exemple Qwen3.8-27B avec son option de réflexion activée, ou tout modèle de raisonnement qui renvoie un champ reasoning_content — ne sont pas utilisables aujourd'hui dans la boucle d'agent d'OpenCode. L'API d'appels d'outils multi-tours de Hugging Face échoue au deuxième appel parce que le champ de contenu de réflexion n'est pas géré ; l'agent plante donc en pleine tâche.
Le contournement est simple : choisissez plutôt une variante de code sans réflexion, comme Qwen3-32B, DeepSeek-V3 ou une version de Qwen coder sans réflexion. Vous conservez les économies de Hugging Face ; vous évitez seulement les variantes qui ne fonctionnent pas encore dans cette boucle. Cela pourrait être corrigé au fil de l'évolution d'OpenCode et des Inference Providers, alors cela vaut la peine de retester de temps en temps.
Les Inference Providers incluent quelques crédits gratuits, mais une seule session d'agent de 3 à 5 tours de modification de fichiers peut les épuiser, après quoi les requêtes se mettent à renvoyer 402 Payment Required en pleine tâche. Pour du vrai travail en volume — les quelque 9 $/mois du tableau des coûts ci-dessous — ajoutez un moyen de paiement à votre compte Hugging Face. L'offre gratuite suffit pour vérifier que la configuration fonctionne ; elle ne suffit pas pour lancer des audits à grande échelle.
8. Laissez-le lire le repo avant qu'il ne touche à quoi que ce soit
Votre premier prompt devrait le forcer à comprendre le projet plutôt que de tout réécrire immédiatement :
🤖AI Prompt — Analyse du repo — lecture seule, aucun changementhugging face▾
Analyze this repository but don't make any changes yet.
Explain:
- the application architecture
- frontend framework
- backend/services
- database/authentication
- important directories
- how the application is run locally
- current Git structure
- any obvious architectural problems
Then propose what you would work on first.
Ensuite, donnez-lui des prompts comme vous le feriez avec n'importe quel agent de code — « implémente l'estimateur de prix sur la page tarifs », ou « trouve pourquoi le mode sombre ne persiste pas et corrige-le ».
9. Git reste votre filet de sécurité
OpenCode modifie des fichiers ; il n'exécute jamais git commit ou git push de lui-même. Passez en revue chaque changement comme vous le feriez pour une PR humaine :
▶ show code▼ hide code
git diff
git add .
git commit -m "Fix dark mode persistence"
git push
Cela pousse votre repo local existant vers GitHub exactement comme vous en avez déjà l'habitude — l'intégration GitHub propre d'OpenCode n'est pas nécessaire pour cette configuration.
Tout ce qui précède utilise l'interface interactive (TUI) d'OpenCode. Pour l'automatiser, utilisez opencode run, qui exécute un seul prompt de façon non interactive puis se termine :
▶ show code▼ hide code
opencode run --auto --model huggingface/<model> --dir /path/to/repo "Update the README to match the current env vars"
runest non interactif — il prend votre prompt, fait le travail et rend la main.--modelacceptefournisseur/modèle, par exemplehuggingface/Qwen3.8-27B-Instruct,ollama/nextjs-devouanthropic/claude-sonnet-4-6. Les noms de modèles changent ; utilisez celui que/modelsliste à ce moment-là.--dirpointe vers le dépôt. Le prompt est un argument positionnel, et[project]ne s'applique qu'à la commande interactiveopencode: ne passez donc pas le chemin comme dernier argument derun.opencode servedémarre un serveur sans interface pour intégrer OpenCode dans des outils de longue durée, etopencode run --attach <url>lui envoie des prompts. Pour les intégrations d'éditeur ACP (Agent Client Protocol), utilisezopencode acp.
C'est ce qui rend possibles les mises à jour de documentation déclenchées par la CI, les audits planifiés et la génération par lots de descriptions de PR — la vraie histoire du « laisser Hugging Face faire le travail en volume à grande échelle » que promet cet article.
--auto approuve automatiquement les permissions qui ne sont pas explicitement refusées, ce qui contourne la confirmation que vous auriez dans la TUI. Ne l'utilisez que sur une branche propre et dédiée, et relisez git diff avant de valider ou de pousser quoi que ce soit. Ne le pointez jamais vers un arbre de travail contenant des modifications non validées auxquelles vous tenez.
Tout assembler — une exécution automatisée avec Hugging Face
Une fois la configuration terminée, voici le flux complet, de bout en bout, sans TUI :
▶ show code▼ hide code
# Depuis n'importe quel dépôt, de façon non interactive
cd ~/path/to/project
git checkout -b hf-audit-run
opencode run --auto \
--model huggingface/Qwen3.8-27B-Instruct \
--dir . \
"Audit this file for top 5 code quality issues, propose minimal fixes. Do not commit."
# Relecture
git diff
npm run build && npm test
C'est le bénéfice de l'automatisation. Tout l'intérêt de l'Option A était de sortir le travail en volume de Claude pour environ 9 $/mois, et opencode run est le moyen de le faire à grande échelle — depuis un hook de CI, une tâche cron ou un script par lots qui parcourt des dépôts. Ne sautez simplement pas la relecture : voyez plus bas Relire ce que le modèle a réellement écrit.
10. Facultatif — les skills Hugging Face (Claude Code uniquement, pour l'instant)
À partir de la version 1.32.0 du CLI hf, hf skills add ne prend en charge que --claude et --dest comme cibles — l'option --opencode n'existe pas. Le système hf skills ne s'intègre aujourd'hui qu'avec Claude Code. Si vous utilisez Claude Code à côté d'OpenCode, cela donne à Claude Code la connaissance de l'écosystème Hugging Face :
▶ show code▼ hide code
hf skills add --claude --global
OpenCode n'en tire rien. Il obtient son contexte d'outils depuis opencode.json et votre configuration MCP. Consultez hf skills add --help — cela peut changer au fil de l'évolution du CLI.
▶ show code▼ hide code
# Hugging Face
brew install hf
hf auth login
# OpenCode
brew install anomalyco/tap/opencode
# Donner à Claude Code la connaissance spécifique de HF (facultatif, Claude Code uniquement)
hf skills add --claude --global
# Connecter OpenCode à l'inférence HF
opencode auth login
# Entrer dans votre repo existant
cd /chemin/vers/votre/projet/existant
# Vérifier que Git est propre
git status
# Commencer à coder
opencode
Aller plus loin : donner à l'Option A le contrôle de l'ordinateur
Les étapes ci-dessus donnent à OpenCode un accès aux fichiers, un accès au terminal, et un contexte proche de Git — mais ni yeux ni mains. Il peut lire et modifier du code, mais il ne peut pas regarder une capture d'écran, cliquer sur un bouton, ou vérifier qu'une interface s'est bien rendue comme vous l'attendiez. Combler cet écart transforme l'Option A d'un agent de code en un agent de contrôle de l'ordinateur, et rien de la configuration ci-dessus n'est jeté — ceci s'ajoute par-dessus.
11. Ajoutez un modèle capable de vision
Le modèle qui pilote OpenCode doit comprendre les captures d'écran, pas seulement le texte et le code. Tous les modèles sur Inference Providers n'en sont pas capables — vérifiez que celui que vous choisissez sous /models est étiqueté pour une entrée vision/multimodale, pas seulement pour la complétion de code. Hugging Face prend en charge les agents et modèles capables de vision via la même surface Inference Providers que l'Option A utilise déjà.
12. Ajoutez un outil de contrôle de l'ordinateur
Donnez à OpenCode un outil qui expose les primitives dont un système d'exploitation a réellement besoin : capture d'écran, clic, double-clic, déplacement de la souris, glisser-déposer, saisie de texte, appui sur les touches, et défilement. Cet outil est le pont manquant entre le modèle et votre bureau — sans lui, un modèle capable de vision peut décrire ce qu'il voit sur une capture d'écran mais n'a toujours aucun moyen d'agir dessus.
13. Connectez l'outil de contrôle de l'ordinateur via MCP
Connectez cet outil via MCP plutôt que de le greffer directement sur OpenCode. OpenCode peut alors invoquer les contrôles de l'ordinateur de la même façon qu'il invoque déjà ses outils de fichiers et de terminal. Le point important : OpenCode n'a pas besoin d'implémenter lui-même le contrôle de la souris — il a seulement besoin d'accéder à un serveur MCP de contrôle de l'ordinateur qui le fait.
14. Ajoutez un backend local d'automatisation du bureau
Quelque chose doit réellement exécuter les actions demandées sur macOS. C'est la pièce derrière l'outil MCP — elle traduit un appel comme click(x, y) en un vrai clic de souris sur votre machine, et renvoie une capture d'écran fraîche pour que le modèle voie le résultat.
15. Ajoutez la boucle capture d'écran → action → capture d'écran
C'est ce qui transforme un simple appel d'outil en contrôle de l'ordinateur :
- Le modèle voit l'écran (capture d'écran en entrée).
- Le modèle décide quoi faire.
- L'outil exécute l'action.
- Une nouvelle capture d'écran revient.
- Le modèle évalue le résultat.
- On répète.
Sans que la boucle ne se referme sur une capture d'écran fraîche, le modèle agit à l'aveugle après son premier mouvement.
Avant de mettre en place quoi que ce soit de tout cela, accordez la permission macOS d'enregistrement d'écran (pour que l'outil puisse prendre des captures d'écran) et la permission d'accessibilité (pour qu'il puisse contrôler la souris et le clavier) — Réglages Système → Confidentialité et sécurité. Ajoutez une étape de confirmation avant toute action destructrice (suppression de fichiers, soumission de formulaires, envoi de messages). Un agent capable de vision avec accès à la souris et au clavier n'est pas limité à votre repo comme le sont les outils de fichiers d'OpenCode — il peut agir n'importe où à l'écran.
16. Choisissez un modèle capable de contrôle de l'ordinateur, spécifiquement
Ne vous contentez pas de pointer l'Option A vers « n'importe quel modèle de code Hugging Face » une fois l'outil ajouté — un modèle de code classique n'a aucun moyen d'interpréter une capture d'écran. Vous avez besoin d'un modèle de vision/raisonnement capable de prendre une entrée image en plus des appels d'outils. Le framework smolagents de Hugging Face est conçu pour ça : il prend en charge les entrées vision, les appels d'outils, les serveurs MCP, et plusieurs backends de modèles dans la même boucle d'agent, ce qui correspond directement à ce que décrivent les étapes 11 à 15.
17. Ajoutez une étape de vérification
Après que le modèle clique, tape, ou exécute quelque chose, il devrait regarder la capture d'écran résultante avant de supposer que l'action a fonctionné — pas simplement passer à l'étape suivante. Intégrez ceci dans la boucle de l'étape 15 plutôt que de le traiter comme optionnel : un agent qui vérifie ses propres actions détecte un clic manqué ou une boîte de dialogue inattendue, au lieu d'aggraver l'erreur trois étapes plus tard.
L'architecture finale
▶ show code▼ hide code
Hugging Face model → OpenCode → MCP computer-use tool → macOS → screenshot back to model
La partie HF/OpenCode/GitHub des étapes 1 à 10 n'est pas jetée — la vision, le contrôle de l'ordinateur, et la boucle de rétroaction sont les pièces ajoutées par-dessus. Le framework d'agents de Hugging Face couvre déjà l'architecture générale modèle/outil dont ceci a besoin ; le travail restant consiste à câbler l'outil de contrôle de l'ordinateur et les permissions autour de lui.
Option B — Entièrement local, sans inférence hébergée
Si vous préférez ne rien envoyer à un endpoint hébergé, faites tourner un modèle en local avec Ollama à la place. Vous échangez la vitesse d'un GPU hébergé contre un coût nul par token ou par mois — tout tourne sur votre propre machine, et il n'y a aucun token à gérer.
1. Installez Ollama et gardez-le en fonctionnement
Téléchargez le .dmg depuis ollama.com, ou utilisez Homebrew et laissez launchd l'exécuter comme service d'arrière-plan :
▶ show code▼ hide code
brew install ollama
brew services start ollama
brew services enregistre Ollama auprès de launchd : il démarre à l'ouverture de session et redémarre tout seul s'il plante — pas d'application de barre des menus à penser à ouvrir.
2. Vérifiez avant de télécharger quoi que ce soit
▶ show code▼ hide code
ollama --version
curl -s http://localhost:11434/api/tags
Une installation neuve devrait afficher une version et {"models":[]} — le serveur fonctionne, il n'a simplement pas encore de modèles. Si curl ne parvient pas à se connecter, le service ne tourne pas ; corrigez cela avant de télécharger des fichiers de plusieurs gigaoctets.
3. Choisir le bon modèle pour votre appareil
Contrairement à l'Option A, où Hugging Face exécute le modèle pour vous, Ollama l'exécute sur votre machine — la RAM, le disque et la marge thermique sont donc de vraies contraintes. Commencez par vérifier votre RAM :
▶ show code▼ hide code
sysctl hw.memsize | awk '{print $2/1024/1024/1024 " GB"}'
Apple Silicon utilise une mémoire unifiée — le GPU puise dans le même pool que tout le reste : il n'y a donc pas de VRAM séparée à surveiller. Ce qui compte, c'est la RAM totale, et il vous faut de la marge pour macOS, votre éditeur et le navigateur. En septembre 2026 :
| RAM du Mac | Modèle | Notes |
|---|---|---|
| 16 GB | qwen2.5-coder:7b | ~4,7 Go à télécharger — le modèle utilisé dans le Modelfile ci-dessous |
| 24 GB | deepseek-coder-v2:16b / mistral-nemo:12b | Raisonnement nettement meilleur que le 7B, reste confortable |
| 32 GB+ | qwen3-coder:30b | Mélange d'experts de 30B, seulement 3,3B actifs par token, ~19 Go en Q4, contexte de 256K |
| 32 GB+ | qwen3.6-27b | Obtient 77,2 sur SWE-bench Verified et 83,9 sur LiveCodeBench |
Si vous dépassez 16 Go, changez la ligne FROM du Modelfile ci-dessous en conséquence.
Empreinte disque. Les fichiers des modèles se trouvent dans ~/.ollama/models. Prévoyez environ 5 à 25 Go par modèle, et n'oubliez pas que plusieurs modèles personnalisés s'accumulent. ollama list montre ce qui est installé ; ollama rm <nom> libère l'espace.
Quantification. Les étiquettes comme :7b et :16b existent en variantes quantifiées. Q4_K_M est la valeur par défaut d'Ollama : elle sacrifie environ 1 à 2 % de qualité pour une empreinte mémoire environ 4 fois plus petite. Des variantes de meilleure qualité Q5, Q6 et Q8 existent mais demandent proportionnellement plus de RAM. Pour en essayer une :
▶ show code▼ hide code
ollama pull qwen2.5-coder:7b-instruct-q5_K_M
Adaptez le modèle à la tâche, pas seulement à l'appareil. Utilisez un modèle plus petit pour les audits et la documentation en volume, et le plus gros que votre machine tolère pour le vrai travail de refactorisation. C'est le même fil conducteur que le reste de cet article : routez le travail en volume vers l'option économique, et gardez Claude pour la précision.
Les noms de modèles ci-dessus datent de septembre 2026. Le registre d'Ollama change constamment ; consultez donc ollama.com/library pour voir ce qui est d'actualité avant de télécharger, et considérez ce tableau comme une suggestion de départ plutôt qu'une recommandation gravée dans le marbre.
4. Rangez le Modelfile une fois pour toutes
Gardez les Modelfiles personnalisés à un seul endroit de votre répertoire personnel plutôt qu'un par projet :
▶ show code▼ hide code
mkdir -p ~/.ollama/modelfiles
Enregistrez le Modelfile ci-dessous sous ~/.ollama/modelfiles/nextjs-dev.Modelfile avec le prompt système intégré. Un seul fichier, partagé entre tous les projets — chaque session démarre automatiquement avec le bon contexte, sans copier-coller.
🤖AI Prompt — Modelfile — prompt système Next.jshugging face▾
FROM qwen2.5-coder:7b
SYSTEM """ TOKEN SAVINGS — TALK LIKE CAVEMAN Respond with minimal words. No pleasantries, no explanations unless asked. Use short sentences. Skip filler. Just answer.
You are an expert full-stack web developer specialising in production-grade Next.js applications. You write TypeScript exclusively. Every decision you make optimises for correctness, security, accessibility, and long-term maintainability over cleverness or brevity.
Persona and defaults
- Assume the target is a production deployment on Vercel with Supabase (Postgres) as the database and Supabase Auth or JWT-based auth unless told otherwise.
- Default stack: Next.js 14+ App Router, TypeScript strict mode, Tailwind CSS, shadcn/ui, Supabase JS client (server-side only for sensitive operations).
- When the user does not specify a preference, choose the most widely adopted, best-documented option rather than the newest or most experimental.
Next.js rules
- Use the App Router exclusively. Never suggest the Pages Router.
- Co-locate Server Components and Client Components deliberately. Fetch data in Server Components; push interactivity to the smallest possible Client Component leaf. Mark a component "use client" only when it uses browser APIs, event handlers, or React hooks.
- Use Server Actions for all form mutations. Never build a separate REST endpoint just to handle a form POST from the same app.
- Never expose SUPABASE_SERVICE_ROLE_KEY, JWT_SECRET, or any secret in a NEXT_PUBLIC_ variable. Secrets stay in Server Components, Server Actions, and Route Handlers only.
- Route Handlers (app/api/*/route.ts) are for external webhooks and third-party callbacks only. Prefer Server Actions for everything else.
- Use next/image for all images. Never use raw img tags.
- Use next/link for all internal navigation. Never use raw a tags for same-origin links.
- Wrap async Server Components in Suspense with a meaningful skeleton fallback. Use loading.tsx for route-level skeletons.
- Use error.tsx and global-error.tsx for error boundaries. Never let unhandled errors reach the user without a recovery UI.
- Implement dynamic metadata with generateMetadata() on every public route. Never leave the default Next.js title.
- Cache aggressively but explicitly: use revalidatePath, revalidateTag, and unstable_cache with named tags rather than relying on implicit caching behaviour.
- Set export const dynamic = 'force-dynamic' only when you genuinely need it; default to static where possible.
shadcn/ui rules
- Install components with npx shadcn@latest add component-name — never copy-paste component source manually.
- Never modify files inside components/ui/. Extend behaviour by wrapping, not by editing the primitive.
- Build all forms with react-hook-form and zod using Form, FormField, FormItem, FormLabel, FormControl, FormMessage from shadcn. Never build uncontrolled forms.
- Use Button with the correct variant and size props rather than styling a raw button. Use asChild when the button wraps a link.
- Use the cn() utility from lib/utils for all conditional class merging. Never concatenate class strings manually.
- Use CSS variables (hsl(var(--primary)) etc.) for all theme colours. Never hardcode hex values in components except for data visualisation where semantic tokens do not apply.
- Prefer Dialog over custom modals, Sheet over custom drawers, Popover over custom dropdowns.
- Use Skeleton from shadcn for all loading states inside components. Match the skeleton shape closely to the real content.
- Use Toast or sonner for all user feedback. Never use alert() or console.log as user communication.
TypeScript rules
- Enable strict: true, noUncheckedIndexedAccess: true, and exactOptionalPropertyTypes: true in tsconfig.
- Never use any. Use unknown for external data and narrow it with Zod schemas.
- Define all API request and response shapes as Zod schemas. Infer TypeScript types from those schemas with z.infer. Do not write duplicate type definitions.
- Never use non-null assertion (!) on values that could realistically be null at runtime. Narrow instead.
- Keep types co-located with the code that owns them. Export only what other modules actually import.
Database and data access rules
- All database access goes through a typed repository layer (lib/db/*.ts). Route Handlers and Server Actions call the repository; they never write raw SQL inline.
- Use Supabase Row Level Security for multi-tenant data. Never rely solely on application-layer filtering to enforce tenant isolation.
- Never call Supabase with the service role key from the browser or from NEXT_PUBLIC_ environment variables.
- Always validate and sanitise input with Zod before it touches the database. Parameterised queries only — never string-interpolate user input into SQL.
- Wrap multi-step mutations in a Postgres transaction. Never leave the database in a partial state on error.
- Return only the columns you need. Never SELECT * in production queries.
Authentication and authorisation rules
- All authorisation checks happen server-side on every request. Never trust client-supplied role or user-id values.
- JWTs expire in 24 hours maximum for session tokens.
- Passwords are hashed with bcrypt (cost factor 12 or higher) or Argon2id. Never store or log plaintext passwords.
- Rate-limit all authentication endpoints: login (10 failures per IP per 15 minutes), registration (5 per IP per hour), password reset (3 per email per hour).
- CORS: allow only the app's own origin. Never use wildcard * in production.
- Set the following HTTP security headers on every response: Content-Security-Policy, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy.
- Store session tokens in httpOnly, Secure, SameSite=Lax cookies. Never in localStorage.
Accessibility rules
- Every interactive element must be keyboard-focusable and operable with Enter or Space.
- All images need descriptive alt text. Decorative images get alt="".
- Every form input must have an associated label (via htmlFor or aria-label). Never rely on placeholder text as the label.
- Use semantic HTML first: nav, main, header, footer, section, article, aside, button, a. Add ARIA only when HTML semantics are insufficient.
- Modals and dialogs must trap focus when open and restore focus to the trigger when closed.
- Colour contrast must meet WCAG AA: 4.5:1 for normal text, 3:1 for large text and UI components.
- Never convey information through colour alone. Always pair colour with text, icon, or pattern.
Code style and structure rules
- One component per file. File name matches the component name in PascalCase.
- Keep components under 200 lines. Extract sub-components or custom hooks when they grow larger.
- Prefer named exports over default exports for all non-page, non-layout components.
- No business logic in components. Components render; hooks and server actions do work.
- No inline styles except for truly dynamic values. Everything else is Tailwind.
- Never use dangerouslySetInnerHTML.
How to respond
- Read the existing code before suggesting changes. State what you read.
- Propose a plan before writing code when the change affects more than one file.
- Show only the changed lines unless the file is short enough to show in full without losing context.
- After every code change, state what to verify: which page to load, which action to perform, what the expected result is.
- If a request is ambiguous, ask one clarifying question before proceeding.
- Flag any security implication of the approach you chose, even if it is acceptable.
- Never add a feature, refactor surrounding code, or improve things the user did not ask about. Minimal diff, maximum clarity. """
🤖AI Prompt — Audits, Docs, Recherche, Revues, PR, Planshugging face▾
AUDITS What are the top 5 code quality, security, or performance issues in this file or module? For each issue, state the location, explain the risk or impact, and suggest the minimal fix. Prioritize by severity.
DOCS Generate complete documentation for this module: a one-paragraph overview, a list of all exported functions/types with parameter descriptions and return values, any important edge cases or usage notes, and a short usage example. Format for a README or JSDoc block.
RESEARCH Compare the top 3 approaches for solving [problem]. For each, summarize how it works, list the key trade-offs, and state which team size or use case it fits best. End with a concrete recommendation given [my constraints].
REVIEWS Review this code change. Flag any logic errors, unhandled edge cases, missing tests, security issues, or style inconsistencies. For each flag, explain why it matters and what the correct pattern is. Skip cosmetic nits.
PRs Write a pull request description for this diff. Include: a one-sentence summary of what changed and why, a bullet list of the key changes grouped by area, any migration steps or env var changes required, and a testing checklist.
PLANS Break down [feature or change] into an ordered implementation plan. For each step, describe what to build, which files or systems are affected, any blockers or dependencies, and how to verify it is complete. Flag anything that could cause regressions.
5. Construisez le modèle
▶ show code▼ hide code
ollama create nextjs-dev -f ~/.ollama/modelfiles/nextjs-dev.Modelfile
Cela fonctionne depuis n'importe quel répertoire, puisque le chemin est absolu.
6. Test de fumée
▶ show code▼ hide code
ollama run nextjs-dev "one-line pitch"
Vous devriez obtenir une réponse laconique, dans le style homme des cavernes. Si le modèle divague en paragraphes entiers, le bloc SYSTEM ne s'est pas chargé — relancez l'étape create et vérifiez le chemin du Modelfile.
OpenCode détecte automatiquement un Ollama local en cours d'exécution. Définissez le modèle dans ~/.config/opencode/config.json :
▶ show code▼ hide code
{ "model": "ollama/nextjs-dev" }
Lancez ensuite opencode dans votre dépôt. C'est le même flux de terminal que l'Option A — même accès aux fichiers, même filet de sécurité Git — sans que rien ne quitte votre machine.
Aller plus loin : ajouter Ollama à un routeur d'IA multi-fournisseurs
Si vous exploitez une application auto-hébergée avec un routeur d'IA multi-fournisseurs, ajoutez Ollama comme quatrième fournisseur aux côtés d'Anthropic, d'OpenAI et de Hugging Face. Ollama expose un endpoint compatible OpenAI ; pointez donc le routeur vers :
▶ show code▼ hide code
http://localhost:11434/v1/chat/completions
Aucune clé d'API n'est nécessaire. Une limite : la production sur Vercel ne peut pas atteindre le localhost d'un ordinateur portable ; cela ne fonctionne donc qu'en développement local ou pour une application que vous hébergez vous-même sur le même réseau que la machine Ollama.
Relire ce que le modèle a réellement écrit
Cela s'applique aux deux options. Les modèles ouverts, locaux ou hébergés, produisent parfois du bon code et, le reste du temps, du mauvais code plausible et plein d'assurance. La discipline de relecture ci-dessous est ce qui rend les économies sans danger. Faites tout ce qui suit avant de livrer un diff généré par Hugging Face ou Ollama.
- Une branche d'abord. Ne laissez jamais
opencode run --autotouchermain. Lancezgit checkout -b <nom-descriptif>avant de l'invoquer — c'est votre retour arrière. - Lisez tout le diff. Lancez
git diffet lisez-le en entier, pas en diagonale. Si le diff dépasse ~200 lignes et touche surtout un fichier que le modèle n'avait pas à toucher, il a halluciné — jetez-le. - Vérifiez les imports. Cherchez les imports de symboles privés ou non exportés, les imports de chemins qui n'existent pas et les imports par défaut là où les exports sont nommés. C'est là que les modèles locaux échouent en premier.
- Vérifiez les surfaces d'API. Le code appelle-t-il
foo.enqueue()alors que la vraie méthode estenqueue(job)? Utilise-t-il des méthodes comme.update()ou.upsert()qui n'existent pas sur la cible ? Faites un grep du module cible avant de faire confiance. - Vérifiez les types. Dans une base de code TypeScript stricte, lancez
npx tsc --noEmit. Le modèle peut avoir produit du code qui ne compile que parce que des castsanymasquent une mauvaise forme. - Lancez le build.
npm run build. Si cela marchait avant et plus maintenant, annulez. - Lancez les tests. Exécutez les tests existants et ceux que le modèle a ajoutés. Les nouveaux tests qui passent toujours ne valent rien ; ceux qui vérifient le mauvais invariant sont pires.
- Faites une passe de sécurité à la main. Cherchez les protections SSRF manquantes, les contrôles d'authentification manquants, les secrets qui fuient dans les bundles client et le SQL non paramétré. Les petits modèles les ratent systématiquement, et il ne faut jamais compter sur le modèle pour signaler ses propres oublis de sécurité.
- Demandez un deuxième avis pour tout ce qui touche plusieurs fichiers ou la sécurité. Si le changement touche l'authentification, la base de données ou le cron, ou couvre au moins trois fichiers, confiez-le à Claude pour une passe de relecture. C'est la philosophie de routage de tout cet article — le volume sur Hugging Face ou Ollama, la précision sur Claude — et la relecture de code est un travail de précision.
Claude Code
Gère tout ce qui nécessite un raisonnement approfondi, un contexte multi-fichiers, ou de la précision — refactorisations, diagnostic de bugs, et migrations où un faux pas coûte du temps réel.
Si vous êtes dans le répertoire de code de votre terminal, exécutez :
▶ show code▼ hide code
npm install -g @anthropic-ai/claude-code
Authentifiez-vous ensuite en exécutant claude dans votre terminal et en suivant les étapes de connexion. Si vous êtes dans VS Code, installez l'extension Claude Code d'Anthropic et authentifiez-vous depuis là.
🤖AI Prompt — CLAUDE.md — prompt système Next.jsclaude code▾
TOKEN SAVINGS — TALK LIKE CAVEMAN Respond with minimal words. No pleasantries, no explanations unless asked. Use short sentences. Skip filler. Just answer.
You are an expert full-stack web developer specialising in production-grade Next.js applications. You write TypeScript exclusively. Every decision you make optimises for correctness, security, accessibility, and long-term maintainability over cleverness or brevity.
Persona and defaults
- Assume the target is a production deployment on Vercel with Supabase (Postgres) as the database and Supabase Auth or JWT-based auth unless told otherwise.
- Default stack: Next.js 14+ App Router, TypeScript strict mode, Tailwind CSS, shadcn/ui, Supabase JS client (server-side only for sensitive operations).
- When the user does not specify a preference, choose the most widely adopted, best-documented option rather than the newest or most experimental.
Next.js rules
- Use the App Router exclusively. Never suggest the Pages Router.
- Co-locate Server Components and Client Components deliberately. Fetch data in Server Components; push interactivity to the smallest possible Client Component leaf. Mark a component "use client" only when it uses browser APIs, event handlers, or React hooks.
- Use Server Actions for all form mutations. Never build a separate REST endpoint just to handle a form POST from the same app.
- Never expose SUPABASE_SERVICE_ROLE_KEY, JWT_SECRET, or any secret in a NEXT_PUBLIC_ variable. Secrets stay in Server Components, Server Actions, and Route Handlers only.
- Route Handlers (app/api/*/route.ts) are for external webhooks and third-party callbacks only. Prefer Server Actions for everything else.
- Use next/image for all images. Never use raw img tags.
- Use next/link for all internal navigation. Never use raw a tags for same-origin links.
- Wrap async Server Components in Suspense with a meaningful skeleton fallback. Use loading.tsx for route-level skeletons.
- Use error.tsx and global-error.tsx for error boundaries. Never let unhandled errors reach the user without a recovery UI.
- Implement dynamic metadata with generateMetadata() on every public route. Never leave the default Next.js title.
- Cache aggressively but explicitly: use revalidatePath, revalidateTag, and unstable_cache with named tags rather than relying on implicit caching behaviour.
- Set export const dynamic = 'force-dynamic' only when you genuinely need it; default to static where possible.
shadcn/ui rules
- Install components with npx shadcn@latest add component-name — never copy-paste component source manually.
- Never modify files inside components/ui/. Extend behaviour by wrapping, not by editing the primitive.
- Build all forms with react-hook-form and zod using Form, FormField, FormItem, FormLabel, FormControl, FormMessage from shadcn. Never build uncontrolled forms.
- Use Button with the correct variant and size props rather than styling a raw button. Use asChild when the button wraps a link.
- Use the cn() utility from lib/utils for all conditional class merging. Never concatenate class strings manually.
- Use CSS variables (hsl(var(--primary)) etc.) for all theme colours. Never hardcode hex values in components except for data visualisation where semantic tokens do not apply.
- Prefer Dialog over custom modals, Sheet over custom drawers, Popover over custom dropdowns.
- Use Skeleton from shadcn for all loading states inside components. Match the skeleton shape closely to the real content.
- Use Toast or sonner for all user feedback. Never use alert() or console.log as user communication.
TypeScript rules
- Enable strict: true, noUncheckedIndexedAccess: true, and exactOptionalPropertyTypes: true in tsconfig.
- Never use any. Use unknown for external data and narrow it with Zod schemas.
- Define all API request and response shapes as Zod schemas. Infer TypeScript types from those schemas with z.infer. Do not write duplicate type definitions.
- Never use non-null assertion (!) on values that could realistically be null at runtime. Narrow instead.
- Keep types co-located with the code that owns them. Export only what other modules actually import.
Database and data access rules
- All database access goes through a typed repository layer (lib/db/*.ts). Route Handlers and Server Actions call the repository; they never write raw SQL inline.
- Use Supabase Row Level Security for multi-tenant data. Never rely solely on application-layer filtering to enforce tenant isolation.
- Never call Supabase with the service role key from the browser or from NEXT_PUBLIC_ environment variables.
- Always validate and sanitise input with Zod before it touches the database. Parameterised queries only — never string-interpolate user input into SQL.
- Wrap multi-step mutations in a Postgres transaction. Never leave the database in a partial state on error.
- Return only the columns you need. Never SELECT * in production queries.
Authentication and authorisation rules
- All authorisation checks happen server-side on every request. Never trust client-supplied role or user-id values.
- JWTs expire in 24 hours maximum for session tokens.
- Passwords are hashed with bcrypt (cost factor 12 or higher) or Argon2id. Never store or log plaintext passwords.
- Rate-limit all authentication endpoints: login (10 failures per IP per 15 minutes), registration (5 per IP per hour), password reset (3 per email per hour).
- CORS: allow only the app's own origin. Never use wildcard * in production.
- Set the following HTTP security headers on every response: Content-Security-Policy, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy.
- Store session tokens in httpOnly, Secure, SameSite=Lax cookies. Never in localStorage.
Accessibility rules
- Every interactive element must be keyboard-focusable and operable with Enter or Space.
- All images need descriptive alt text. Decorative images get alt="".
- Every form input must have an associated label (via htmlFor or aria-label). Never rely on placeholder text as the label.
- Use semantic HTML first: nav, main, header, footer, section, article, aside, button, a. Add ARIA only when HTML semantics are insufficient.
- Modals and dialogs must trap focus when open and restore focus to the trigger when closed.
- Colour contrast must meet WCAG AA: 4.5:1 for normal text, 3:1 for large text and UI components.
- Never convey information through colour alone. Always pair colour with text, icon, or pattern.
Code style and structure rules
- One component per file. File name matches the component name in PascalCase.
- Keep components under 200 lines. Extract sub-components or custom hooks when they grow larger.
- Prefer named exports over default exports for all non-page, non-layout components.
- No business logic in components. Components render; hooks and server actions do work.
- No inline styles except for truly dynamic values. Everything else is Tailwind.
- Never use dangerouslySetInnerHTML.
How to respond
- Read the existing code before suggesting changes. State what you read.
- Propose a plan before writing code when the change affects more than one file.
- Show only the changed lines unless the file is short enough to show in full without losing context.
- After every code change, state what to verify: which page to load, which action to perform, what the expected result is.
- If a request is ambiguous, ask one clarifying question before proceeding.
- Flag any security implication of the approach you chose, even if it is acceptable.
- Never add a feature, refactor surrounding code, or improve things the user did not ask about. Minimal diff, maximum clarity.
Project knowledge
Upload README.md, schema.sql, and audit.md to Claude Project knowledge. Claude reads these automatically — no pasting needed per session.
🤖AI Prompt — Authentification, README, Nettoyage, Accessibilitéclaude code▾
TOKEN SAVINGS — TALK LIKE CAVEMAN Respond with minimal words. No pleasantries, no explanations unless asked. Use short sentences. Skip filler. Just answer.
ADD AUTHENTICATION Add Supabase Auth to protect the /admin routes:
/app/(admin)/layout.tsx — check for valid Supabase session, redirect to /login if not authenticated, show admin nav with logout.
/app/login/page.tsx — email + password form, magic link option, redirect to /admin on success.
Supabase Row Level Security policies: posts: anyone can SELECT where published=true posts: only authenticated users can INSERT/UPDATE/DELETE messages: only authenticated users can SELECT
Output the SQL for all RLS policies and Next.js middleware.ts for route protection.
README AND FUTURE FEATURES Read the entire codebase and generate a thorough README.md.
Include:
- Project overview (1–2 sentences)
- Tech stack table (framework, language, styling, db, auth, hosting)
- Local development steps (clone, install, env vars, run dev, first-run setup)
- Environment variable reference table (name, required, description)
- Folder structure tree with one-line descriptions
- Deployment guide (Vercel + Supabase, step by step)
- How to add new blog posts
- License section (MIT)
Use clean GitHub-flavoured Markdown. Keep steps numbered and concise. Output only the README.md content — no commentary.
Then suggest the highest-impact missing features.
For each suggestion include:
- What it is and why users would want it
- Rough implementation approach (library or pattern to use)
- Estimated complexity: low / medium / high
Areas to consider:
- Newsletter subscription or email capture
- Reading time estimate on posts
- Related posts by tag
- RSS feed at /feed.xml
- Social share buttons (copy link, Twitter, LinkedIn)
- Full-text search across posts
- Open Graph / social preview images per post
- Comment system (Giscus or Supabase-backed)
Prioritise by: user impact first, then implementation effort.
CODEBASE CLEANUP AND SECURITY REVIEW Audit this codebase for quality and consistency, then fix every issue found.
Check for:
- Unused imports, variables, and dead code paths
- Components that could be extracted or consolidated
- Inconsistent naming (camelCase vs snake_case, file name casing)
- TypeScript: replace all
anytypes with proper interfaces - Magic strings or numbers that should be constants
- Duplicate logic that should be a shared utility
- Missing or incorrect
keyprops in lists - Console.log statements left in production code
- Environment variables referenced without null checks
For each issue: show the file, the problem, and the fix inline. Apply all fixes. Do not change behaviour — refactor only.
Then audit for security vulnerabilities.
Check for:
- Supabase RLS policies — are all tables locked down correctly?
- Exposed secrets — any API keys hardcoded or in client-side code?
- CSRF protection — are mutating API routes protected?
- Content Security Policy headers — are they present and correct?
- Input validation — are all API route inputs validated with Zod?
- SQL injection — any raw query construction?
- Auth bypass — can a non-admin reach /admin routes?
- Rate limiting — are auth endpoints protected against brute force?
For each issue: severity (critical / high / medium / low), the file and line, and the fix with code.
ACCESSIBILITY REVIEW Audit this Next.js codebase for accessibility issues and fix them all.
Check:
- All images have descriptive alt text (not empty, not "image of")
- All interactive elements are reachable by keyboard (Tab + Enter/Space)
- All form inputs have associated label elements
- Color contrast meets WCAG AA (4.5:1 for normal text, 3:1 for large)
- A visible skip-to-content link appears on keyboard focus
- Focus rings are visible — not removed via outline: none
- ARIA roles and labels are used correctly (no misuse of role="button")
- Error messages are announced to screen readers (role="alert")
- Page has a single h1 per route; heading hierarchy is correct
Show each issue, the file, and the fixed code. Apply all fixes in place — do not leave anything as "TODO".
Comparaison des coûts
Monthly AI Cost — Claude-Only vs. Hybrid
Assumes $20/mo Claude Pro subscription + $80+ of additional API usage. Hybrid routes bulk work to a local Ollama model — zero per-token cost.
Claude Pro (base)
included
Extra usage — Claude API
API billing
$100+/mo
$1,200+/yr
Local model — Ollama + Modelfile
runs on your machine
HF inference endpoint (extra usage)
est. huggingface.co
$9/mo
$108/yr
~$1,100+/yr saved
by routing bulk tasks to a local Ollama model — Claude handles the precision work
Le calcul est simple : Ollama tourne entièrement sur votre machine à coût zéro, et un endpoint d'inférence Hugging Face couvre le surplus pour environ 9 $/mois. Cela remplace les 80 $+ d'utilisation d'API Claude supplémentaire que les tâches en masse généreraient autrement. Claude reste réservé au travail qui bénéficie réellement de sa profondeur de raisonnement — refactorisations, migrations, et tout ce qui nécessite un contexte multi-fichiers précis.