5 min de lecture - Monorepos NestJS : compromis d'architecture et d'outillage
Backend Architecture & Monorepo Strategy
Date de publication 30 juin 2025 · Auteur Exceev Consulting
NestJS prend en charge une organisation standard ou en monorepo. Sa documentation présente le mode monorepo comme une possibilité pour les équipes ou les environnements multi-projets, pas comme le choix par défaut de tous les backends. La forme du dépôt doit suivre le couplage, la propriété et les contraintes de release.
Ce guide couvre les patterns, l'outillage et les compromis pour faire fonctionner des applications NestJS dans un monorepo, de la configuration initiale jusqu'au déploiement en production.
Un monorepo NestJS peut aider lorsque plusieurs projets partagent des bibliothèques ou exigent des modifications coordonnées. Il élargit aussi le rayon d'impact de la configuration et des accès au dépôt. Le CLI Nest possède son propre mode workspace ; Nx constitue une option distincte lorsque son graphe de projets, son cache et ses tâches « affected » répondent aux besoins de l'équipe.
Périmètre d'un monorepo
Un monorepo est un dépôt unique contenant plusieurs projets qui peuvent être construits, testés et déployés indépendamment. Ce n'est pas un monolithe, chaque projet du dépôt peut avoir son propre pipeline de déploiement et son propre runtime.
La taille de l'organisation ne décide pas de l'architecture. Une petite équipe peut souffrir de limites floues, tandis qu'une grande équipe peut exploiter plusieurs dépôts. Évaluez le graphe de dépendances et la propriété du code au lieu de copier la structure d'une autre entreprise.
Pourquoi NestJS s'intègre naturellement au modèle monorepo
L'architecture modulaire de NestJS, où chaque fonctionnalité est un module avec des imports et exports explicites, s'articule naturellement avec les bibliothèques partagées d'un monorepo :
Gestion visible des dépendances. Un workspace peut centraliser la politique de dépendances et rendre les versions concurrentes plus faciles à repérer. Le gestionnaire de paquets peut encore installer plusieurs versions ; le dépôt ne supprime donc pas la dérive.
Commits coordonnés. Un DTO partagé et ses consommateurs connus peuvent évoluer dans une seule revue. Cela réduit une partie de la coordination entre dépôts, mais agrandit aussi le périmètre touché par un changement ou un droit d'accès.
Partage de code sans publication. Les bibliothèques partagées (guards d'authentification, intercepteurs de journalisation, entités TypeORM) sont importées directement, aucun registre npm privé n'est nécessaire.
Outillage partagé. Le dépôt peut fournir des réglages communs de lint, formatage et CI. Certains projets peuvent néanmoins exiger des cibles de test, runtimes ou pipelines de release distincts.
Mettre en place un monorepo NestJS piloté par Nx
Nx est l'un des outils de monorepo établis dans l'écosystème Node.js. Voici une configuration pratique à évaluer, et non la seule manière prise en charge pour organiser des projets NestJS :
npx create-nx-workspace@latest my-platform --preset=nest
Cela génère un workspace avec une seule application NestJS. Ajoutez d'autres applications et bibliothèques selon vos besoins :
# Add a second NestJS service
nx g @nx/nest:application api-gateway
# Create a shared library
nx g @nx/nest:library shared-auth
nx g @nx/nest:library shared-dto
Structure du workspace
my-platform/
├── apps/
│ ├── api-gateway/ # HTTP gateway service
│ │ └── src/
│ ├── billing-service/ # Billing microservice
│ │ └── src/
│ └── notification-service/
│ └── src/
├── libs/
│ ├── shared-auth/ # Auth guards, strategies, decorators
│ ├── shared-dto/ # Request/response DTOs, validation
│ ├── shared-database/ # TypeORM entities, migrations
│ └── shared-logging/ # Logger interceptors, correlation IDs
├── nx.json
├── tsconfig.base.json
└── package.json
Alias de chemins TypeScript
Nx configure automatiquement les alias de chemins afin que les bibliothèques partagées soient importables proprement :
// In any app or library
import { AuthGuard, CurrentUser } from '@my-platform/shared-auth'
import { CreateUserDto, UserResponseDto } from '@my-platform/shared-dto'
import { LoggingInterceptor } from '@my-platform/shared-logging'
Patterns de bibliothèques partagées
Bibliothèque d'authentification
Une bibliothèque d'authentification partagée fournit les guards, décorateurs et stratégies utilisés par l'ensemble des services :
// libs/shared-auth/src/lib/guards/jwt-auth.guard.ts
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
canActivate(context: ExecutionContext) {
return super.canActivate(context)
}
}
// libs/shared-auth/src/lib/decorators/current-user.decorator.ts
export const CurrentUser = createParamDecorator((data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest()
return request.user
})
Bibliothèque de DTO avec validation
Les DTO partagés garantissent des formats de requête/réponse cohérents entre les services :
// libs/shared-dto/src/lib/user.dto.ts
export class CreateUserDto {
@IsEmail()
email: string
@IsString()
@MinLength(8)
password: string
}
export class UserResponseDto {
id: string
email: string
createdAt: Date
}
Communication entre microservices
Au sein d'un monorepo, les microservices NestJS peuvent communiquer via plusieurs couches de transport :
TCP pour les appels synchrones de service à service (faible latence, configuration simple).
RabbitMQ ou Redis pour une communication événementielle (découplée, résiliente).
gRPC pour une communication haute performance basée sur des schémas (typage fort, sérialisation efficace).
// api-gateway calling billing-service via TCP
@Injectable()
export class BillingClient {
private client: ClientProxy
constructor() {
this.client = ClientProxyFactory.create({
transport: Transport.TCP,
options: { host: 'localhost', port: 3001 },
})
}
calculateBill(userId: string): Observable<BillingAmount> {
return this.client.send('calculate_bill', { userId })
}
}
Stratégies CI/CD pour les monorepos
Le temps de build constitue l'une des préoccupations d'un monorepo. Nx fournit deux mécanismes utiles, mais leur valeur dépend d'un graphe exact et de tâches compatibles avec le cache :
Les commandes « affected ». Ne construire, tester et linter que les projets impactés par une modification donnée :
nx affected --target=build
nx affected --target=test
Mise en cache des calculs. Nx met en cache les résultats des tâches localement et (avec Nx Cloud) à distance. Si une bibliothèque n'a pas changé, son résultat de build est réutilisé.
Un pipeline CI concret :
# .github/workflows/ci.yml
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: npm ci
- run: npx nx affected --target=lint --base=origin/main
- run: npx nx affected --target=test --base=origin/main
- run: npx nx affected --target=build --base=origin/main
Quand le monorepo n'est pas le bon choix
Un monorepo ajoute de la charge opérationnelle. Évitez-le si :
- Les services sont réellement indépendants et ne partagent aucun code
- Les équipes appartiennent à des organisations différentes avec des cadences de release différentes
- Vous avez moins de deux services déployables
- Votre infrastructure CI ne peut pas absorber un dépôt plus volumineux
Démarrez petit, ajoutez des services au fur et à mesure que la complexité l'exige
NestJS et Nx peuvent fonctionner ensemble pour des backends multi-projets, mais un monorepo redistribue la coordination au lieu de la supprimer. Commencez par une application et une bibliothèque réellement partagée, mesurez la friction en CI et sur la propriété du code, puis ajoutez des projets tant que le dépôt commun reste utile. Besoin d'aide pour concevoir l'architecture de votre monorepo NestJS ? Parlons-en.
Sources consultées
- modes workspace et monorepo de NestJS, consultés le 27 août 2026
- présentation des monorepos par Nx, consultée le 27 août 2026
- documentation Nx sur les tâches affectées, consultée le 27 août 2026
Parlons-en.
Exceev accompagne les startups et les PME en stratégie, intégration IA, ingénierie sur mesure et montée en compétences technologiques.