Une seule codebase, plusieurs produits : comment les monorepos accélèrent les équipes
Diviser un produit en dépôts séparés paraît propre jusqu'au moment où vous devez partager des types, coordonner des releases ou faire tourner un seul pipeline CI. Les monorepos résolvent ça — voici quand faire le changement et comment le structurer pour qu'il reste gérable à mesure que l'équipe grandit.
À mesure que les bases de code grandissent et que les équipes se développent, la façon dont vous organisez vos dépôts devient une décision architecturale critique. Les monorepos sont apparus comme un pattern puissant adopté par des géants de la tech comme Google, Meta et Microsoft. Dans ce guide, j'explique ce que sont les monorepos, quand les utiliser, et comment ils se comparent aux approches multi-dépôts traditionnelles.
Qu'est-ce qu'un Monorepo ?
Un monorepo est un dépôt unique contenant plusieurs projets distincts avec des relations bien définies. Le mot clé ici est « distinct ». Un monorepo ne consiste pas simplement à mettre tout votre code dans un seul dossier. C'est une approche structurée où chaque projet maintient ses propres frontières tout en partageant une infrastructure commune.
Pensez-y comme à un immeuble : chaque appartement (projet) est autonome avec son propre agencement, mais ils partagent tous la même fondation, les mêmes services et la même gestion.
Monorepo vs Monolithe vs Polyrepo
Ces termes sont souvent confondus, mais ils représentent des concepts fondamentalement différents :
POLYREPO MONOREPO MONOLITHE
repo-frontend/ my-company/ my-app/
├── package.json ├── apps/ ├── package.json
└── src/ │ ├── web/ └── src/
│ ├── mobile/ ├── frontend/
repo-backend/ │ └── api/ ├── backend/
├── package.json ├── packages/ ├── shared/
└── src/ │ ├── ui/ └── utils/
│ └── utils/
repo-shared/ ├── package.json (fortement couplé,
├── package.json └── turbo.json pas de frontières)
└── src/
(projets multiples,
(dépôts séparés, frontières claires,
versions indépendantes) outillage partagé)
Polyrepo (Dépôts Multiples)
- Chaque projet vit dans son propre dépôt
- Versionnement et releases indépendants
- Nécessite de publier des packages pour partager du code
- Les changements inter-projets nécessitent plusieurs PRs
Monorepo (Dépôt Unique, Projets Multiples)
- Tous les projets dans un dépôt avec des frontières claires
- Outillage et configuration partagés
- Imports directs entre projets (pas de publication)
- Commits atomiques sur plusieurs projets
Monolithe (Base de Code Unique, Sans Frontières)
- Tout dans une base de code fortement couplée
- Pas de séparation claire entre les composants
- Les changements dans une zone peuvent casser des fonctionnalités non liées
- Difficile de faire évoluer les équipes indépendamment
Les Problèmes des Polyrepos
Avant de comprendre pourquoi les monorepos existent, examinons les points de friction dans les configurations multi-dépôts traditionnelles :
Surcharge du Partage de Code
Vous voulez partager une fonction utilitaire entre deux projets ? Dans un polyrepo, vous devez :
- Créer un nouveau dépôt pour le package partagé
- Configurer des pipelines de build et de publication
- Configurer l'accès au registre npm/package
- Gérer le versionnement sémantique
- Mettre à jour les consommateurs lors des modifications
Cette surcharge décourage le partage, conduisant à la duplication de code entre les dépôts.
Changements Inter-Dépôts
Imaginez trouver un bug dans une bibliothèque partagée. Dans un polyrepo :
- Corriger le bug dans le dépôt de la bibliothèque
- Créer une PR, attendre la revue, merger
- Publier une nouvelle version
- Mettre à jour la dépendance dans chaque dépôt consommateur
- Créer des PRs pour chaque consommateur, attendre les revues, merger
Une simple correction de bug devient un effort de coordination de plusieurs jours.
Outillage Incohérent
Chaque dépôt évolue indépendamment, conduisant à :
- Des règles et configurations de linting différentes
- Des frameworks de test et conventions variés
- Des processus de build incohérents
- Des pipelines CI/CD différents à maintenir
L'Enfer des Dépendances
Différents projets peuvent dépendre de différentes versions de la même bibliothèque, causant :
- Des problèmes de compatibilité lors de l'intégration
- Des vulnérabilités de sécurité dans les dépendances obsolètes
- Des tailles de bundle augmentées à cause des dépendances dupliquées
Avantages des Monorepos
Les monorepos répondent à ces défis grâce à une infrastructure unifiée et des changements atomiques.
Partage de Code Sans Frais
Créer un package partagé est aussi simple que de créer un nouveau dossier. Pas d'infrastructure de publication, pas de gestion de version pour le code interne. Il suffit d'importer et d'utiliser.
import { Button } from "@repo/ui";
import { formatDate } from "@repo/utils";
Commits Atomiques
Modifiez un composant partagé et mettez à jour tous les consommateurs dans un seul commit. Pas de coordination entre dépôts, pas de mise à jour de version, pas d'attente de publication.
git commit -m "refactor: update Button API across all apps"
Source Unique de Vérité
- Une configuration ESLint pour tous les projets
- Une configuration TypeScript à maintenir
- Un pipeline CI/CD qui gère tout
- Un seul endroit pour trouver n'importe quel morceau de code
Gestion Simplifiée des Dépendances
Tous les projets utilisent la même version des dépendances externes. Mettez à jour React une fois, et chaque projet reçoit la mise à jour. Plus de « quelle version de lodash utilise le projet X ? »
Collaboration Améliorée
- Les développeurs peuvent facilement contribuer à n'importe quel projet
- La revue de code détecte les problèmes inter-projets
- La propriété partagée réduit les silos
- Les nouveaux membres de l'équipe s'intègrent plus rapidement avec un outillage unifié
Refactoring à Grande Échelle
Renommer une fonction utilisée dans 50 fichiers de 10 projets ? Dans un monorepo, c'est une seule opération de recherche-remplacement avec une PR. Dans les polyrepos, c'est des semaines de coordination.
Défis des Monorepos
Les monorepos ne sont pas sans compromis. Comprendre ces défis vous aide à prendre une décision éclairée.
Complexité de l'Outillage
Les outils standard comme npm et git ont été conçus pour des dépôts mono-projet. Les monorepos nécessitent un outillage spécialisé :
- Orchestration de build (Turborepo, Nx, Bazel)
- Gestion des workspaces (npm/yarn/pnpm workspaces)
- CI/CD sélectif (ne builder que ce qui a changé)
Taille du Dépôt
À mesure que le dépôt grandit :
- Les opérations git ralentissent
- Les temps de clonage augmentent
- Les performances de l'IDE peuvent en souffrir
Les solutions incluent les clones superficiels, les checkouts épars, et des outils comme Git LFS pour les fichiers volumineux.
Contrôle d'Accès
L'hébergement Git traditionnel fournit des permissions au niveau du dépôt. Dans un monorepo :
- Tout le monde peut voir tout le code (peut être une préoccupation de sécurité)
- Les permissions granulaires nécessitent un outillage supplémentaire
- Les fichiers CODEOWNERS aident mais ont des limitations
Temps de Build
Sans outillage approprié, chaque changement déclenche un rebuild complet de tout. C'est là que des systèmes de build comme Turborepo deviennent essentiels, fournissant :
- Builds incrémentiels (ne rebuilder que ce qui a changé)
- Mise en cache (ne jamais rebuilder la même chose deux fois)
- Exécution parallèle (utiliser tous les cœurs CPU)
Quand Utiliser un Monorepo
Les monorepos brillent dans des scénarios spécifiques :
Bon Choix
- Applications multiples liées : Une app web, une app mobile et une API qui partagent des types et des utilitaires
- Bibliothèques de composants : Composants UI consommés par plusieurs applications
- Microservices avec contrats partagés : Services nécessitant des types API cohérents
- Applications full-stack : Frontend et backend partageant la logique de validation
- Équipes collaborant fréquemment : Équipes transverses travaillant sur des fonctionnalités interconnectées
Mauvais Choix
- Projets non liés : Projets sans code ou dépendances partagés
- Cycles de release différents : Projets nécessitant un versionnement complètement indépendant
- Contrôle d'accès strict : Quand les équipes ne peuvent absolument pas voir le code des autres
- Migration legacy : Forcer des projets legacy non liés ensemble
Comparaison des Outils Monorepo
Plusieurs outils existent pour gérer efficacement les monorepos. Voici comment les principaux acteurs se comparent :
Turborepo
- Focus : JavaScript/TypeScript
- Points forts : Configuration simple, excellent cache, intégration Vercel
- Idéal pour : Projets JS/TS voulant une adoption rapide
Nx
- Focus : JavaScript/TypeScript avec écosystème de plugins
- Points forts : Fonctionnalités riches, génération de code, visualisation du graphe de dépendances
- Idéal pour : Équipes enterprise voulant un outillage complet
Bazel
- Focus : Polyglotte (n'importe quel langage)
- Points forts : Exécution distribuée, builds hermétiques, échelle massive
- Idéal pour : Grandes organisations avec des stacks technologiques diversifiées
Lerna
- Focus : Publication de packages JavaScript
- Points forts : Versionnement de packages, génération de changelog
- Idéal pour : Publier plusieurs packages npm
Rush
- Focus : TypeScript enterprise
- Points forts : Politiques strictes, prévention des dépendances fantômes
- Idéal pour : Grandes bases de code TypeScript avec des exigences strictes
Fonctionnalités Essentielles d'un Monorepo
Lors de l'évaluation des outils monorepo, recherchez ces capacités :
Performance
- Cache local : Ne pas rebuilder les packages inchangés
- Cache distant : Partager les artefacts de build entre l'équipe et le CI
- Exécution parallèle : Exécuter les tâches indépendantes simultanément
- Détection des changements : N'exécuter les tâches que pour les packages modifiés
Expérience Développeur
- Graphe de dépendances : Comprendre les relations entre packages
- Orchestration des tâches : Définir les dépendances de tâches de manière déclarative
- Commandes cohérentes : Les mêmes scripts fonctionnent dans tous les packages
- Mode watch : Rebuilder lors des changements de fichiers pendant le développement
Maintenabilité
- Génération de code : Scaffolding cohérent de nouveaux packages
- Contraintes : Imposer les frontières architecturales
- Analyse du workspace : Détecter les dépendances circulaires
- Outils de migration : Mettre à jour les dépendances dans tous les packages
Meilleures Pratiques Monorepo
Structurez Clairement Votre Workspace
my-monorepo/
├── apps/ # Applications déployables
│ ├── web/
│ ├── mobile/
│ └── api/
├── packages/ # Bibliothèques partagées
│ ├── ui/
│ ├── utils/
│ └── config/
└── tooling/ # Outils de build et de dev
├── eslint/
└── typescript/
Définissez des Frontières de Packages Claires
Chaque package doit avoir une responsabilité unique. Évitez de créer des packages « utils » qui deviennent des fourre-tout. À la place :
@repo/date-utilspour le formatage de dates@repo/validationpour la validation de formulaires@repo/api-clientpour la communication API
Utilisez une Nomenclature Cohérente
Adoptez une convention de nommage pour les packages internes :
{
"name": "@repo/ui",
"name": "@repo/utils",
"name": "@repo/config-eslint"
}
Imposez les Frontières
Empêchez les packages d'importer ce qu'ils ne devraient pas :
- Les apps peuvent importer depuis les packages
- Les packages ne doivent pas importer depuis les apps
- Les packages UI ne doivent pas importer du code backend
Investissez dans le CI/CD
- Activez le cache distant pour accélérer les builds CI
- Utilisez la détection des changements pour ne tester que les packages modifiés
- Parallélisez les tâches indépendantes
- Mettez en cache les dépendances entre les runs CI
Conclusion
Les monorepos ne sont pas une solution miracle, mais ils offrent des avantages convaincants pour les équipes construisant des applications interconnectées. Les points clés :
- Monorepo ne signifie pas monolithe : Les monorepos bien structurés maintiennent des frontières claires entre les projets.
- Le partage de code devient trivial : Pas d'infrastructure de publication nécessaire pour les packages internes.
- Les changements atomiques réduisent la coordination : Mettez à jour le code partagé et les consommateurs dans un seul commit.
- L'outillage est essentiel : Investissez dans des systèmes de build comme Turborepo ou Nx pour gérer la complexité.
- Pas pour tout le monde : Évaluez si vos projets bénéficient réellement d'une infrastructure partagée.
Si votre équipe construit plusieurs applications liées avec du code partagé, un monorepo peut considérablement améliorer la productivité des développeurs et la qualité du code. Commencez petit, investissez dans l'outillage, et laissez les bénéfices s'accumuler à mesure que votre base de code grandit.
Écrit par

Tech Lead et Ingénieur Full Stack pilotant une équipe de 5 ingénieurs chez Fygurs (Paris, Remote) sur un SaaS cloud-native Azure. Diplômé de 1337 Coding School (42 Network / UM6P). Écrit sur l'architecture, l'infrastructure cloud et le leadership technique.