Tous les articles et vidéos

Architecture frontend en entreprise : les frontières d'abord

L'architecture frontend en entreprise, ce sont des frontières : des couches, un contrat d'import imposé par le , ou non, rarement.

Adil Ben Moussa
08 novembre 2026· 5 min
Architecture frontend en entreprise : les frontières d'abord

Un importe un « juste pour cette fois ». Cinq ans plus tard, la moitié du dossier ui connaît le backend, et personne ne peut changer le style d'un bouton sans provoquer une régression dans les virements. C'est ainsi que vieillissent les frontends d'entreprise : pas à cause d'une mauvaise décision, mais d'une frontière que personne n'a fait respecter.

L'architecture est la partie qui survit au framework, c'est pourquoi elle ouvre cette série. La question n'est pas de savoir quel pattern choisir. Il s'agit de savoir quelles lignes vos équipes n'ont pas le droit de franchir, et ce qui les en empêche.

Des couches avec un contrat « peut importer »

Découpez le code par type, pas seulement par fonctionnalité : domain (modèles et règles purs), data-access (le seul code qui parle au backend), ui (des entrées et des sorties, rien d'autre), feature (qui relie les trois) et app (le shell et les routes). Puis écrivez qui a le droit d'importer qui.

Avec une seule équipe, cela ressemble à du cérémonial. À partir de la deuxième, c'est la seule chose qui sépare leur travail. La règle utile est courte : ui n'atteint jamais data-access, domain n'importe rien, et aucun code moderne n'importe le code .

Une règle dans un wiki s'érode. Mettez-la dans le lint.

permet de poser un tag sur chaque projet et de dire quels tags peuvent dépendre de quels autres. Sa propre documentation en donne la raison en une ligne : « Si tous peuvent dépendre librement les uns des autres, le chaos s'installera et le workspace deviendra ingérable. » Vous n'êtes pas sur Nx ? « fait respecter les frontières de modules et les règles de dépendances en TypeScript », il fonctionne donc aussi dans un simple projet CLI.

Tout l'intérêt est dans l'erreur de lint. Un relecteur se fatigue un vendredi après-midi. La règle, non.

Monorepo ou polyrepo

Nx le dit sans détour : avec l'outillage moderne, « le choix est surtout organisationnel ». La même page conseille un « quand un contrôle d'accès strict au niveau du dépôt est une exigence ferme, ou quand les équipes partagent peu de code ».

En entreprise, j'en ferais plutôt un test. Vos équipes partagent-elles un , un modèle de domaine et un même  ? Alors un seul dépôt, avec des frontières à l'intérieur. Des produits distincts livrent-ils à leur propre rythme sans presque rien partager ? Alors des dépôts séparés. Un monorepo n'impose pas non plus une release unique : les projets sont construits à partir du même , mais « les équipes décident quand un tag arrive en production ».

Micro-frontends : le plus souvent, non

Les micro-frontends sont des « applications frontend livrables indépendamment », assemblées en un seul produit. Le gain est réel : chaque équipe déploie de son côté. Le coût l'est aussi. Le même article prévient que « des bundles JavaScript construits indépendamment peuvent dupliquer des dépendances communes », et demande si vous avez « la maturité technique et organisationnelle nécessaire ».

Mon test : choisissez-les quand des organisations distinctes doivent déployer indépendamment dans un même shell. Ne les choisissez pas pour réparer un désordonné. Un monolithe sans frontières devient cinq dépôts sans frontières, avec un contrat à l'exécution en plus.

Les micro-frontends ne réparent pas une frontière manquante. Ils la déplacent à l'exécution.

Le design system et le coin legacy

Le design system est une bibliothèque comme une autre, et ses sont le contrat. Les composants lisent une couleur par son rôle, pas par sa valeur hexadécimale : un changement d'identité visuelle touche alors un fichier, pas quatre cents.

Le coin legacy reçoit le traitement inverse : gelé, encapsulé, et importé par aucun nouveau code. Dans une application hybride , « chaque élément du DOM de la page appartient à un seul framework », et le graphe d'imports doit dire la même chose. La flèche va dans un seul sens, de l'ancien vers le nouveau, pour que l'ancien code reste supprimable.

Consignez chaque franchissement

Il arrive qu'une frontière doive bouger. C'est acceptable, à condition de l'écrire. Un (ADR) « consigne une seule décision d'architecture et sa justification », et l'équipe suivante aura davantage besoin de la justification que du code.

Sur Atlas Bank

Atlas Bank, l'application de démonstration de cette série, inscrit le contrat dans eslint.config.mjs. Voici les lignes de ui, feature et legacy :

  {
    sourceTag: 'type:ui',
    onlyDependOnLibsWithTags: ['type:ui', 'type:domain'],
  },
  {
    sourceTag: 'type:feature',
    onlyDependOnLibsWithTags: [
      'type:feature',
      'type:ui',
      'type:data-access',
      'type:domain',
    ],
  },
  {
    sourceTag: 'type:legacy',
    onlyDependOnLibsWithTags: [
      'type:legacy',
      'type:data-access',
      'type:domain',
    ],
  },

npm run lint:arch échoue quand ui importe un store. sheriff.config.ts dit la même chose avec Sheriff, pour les équipes sans Nx. L'écran legacy en NgModule de libs/legacy/transfers peut lire les stores modernes, et aucune bibliothèque moderne ne peut l'importer. L'AGENTS.md du dépôt ajoute la moitié humaine : « Franchir une frontière de bibliothèque exige un lien vers un ADR dans la PR. » Les couleurs vivent dans apps/atlas/src/styles/tokens, et npm run check:tokens échoue sur une couleur brute dans n'importe quelle autre feuille de style (le coin legacy gelé garde son ancienne apparence jusqu'à sa suppression).

Ce que j'ai laissé de côté, et pourquoi

  • Clean architecture ou comme étiquettes. Les couches ci-dessus ont cette forme. Le nom ne change aucune décision.
  • Les détails de . Un outillage qui change chaque année. Décidez d'abord des micro-frontends ; l'outil suit.
  • Monolithe contre . Un débat de backend.
  • . Le niveau du code, pas celui du système.

Dès lundi

  • Dessinez vos bibliothèques et les flèches entre elles. Chaque flèche que vous n'aviez pas prévue est une règle potentielle.
  • Ajoutez une règle au lint, celle qui fait le plus mal (souvent ui vers data-access). Laissez-la échouer, puis corrigez ou consignez chaque cas.
  • Écrivez le premier ADR pour le franchissement que vous ne pouvez pas encore supprimer.

Ensuite : la partie 2, sur l'état.

Pour votre agent de code

Les règles de cet article, écrites pour un agent. Collez-les dans votre AGENTS.md, enregistrez-les comme , ou indiquez le fichier à votre agent.

Pour votre agent de code Télécharger le .md
# Frontend architecture rules for enterprise apps

Source: https://tt-tech.io/blog/frontend-architecture-enterprise-boundaries
For Angular and React frontends. Add to AGENTS.md or save as a skill. Your project's own rules win where they differ.

## Rules

1. Split code by type, not only by feature: `domain` (pure models and rules), `data-access` (the only code that talks to the backend), `ui` (inputs and outputs only), `feature` (wires the three) and `app` (shell and routes). Put new code in the layer it belongs to.
2. Keep the "may import" contract: `ui` never imports `data-access`, `domain` imports nothing, and nothing modern imports the legacy code.
3. Enforce boundaries in lint, not in a wiki. On Nx, tag every project and set which tags may depend on which (`onlyDependOnLibsWithTags`). Without Nx, use Sheriff.
4. When the boundary lint fails, let it fail: fix the import, or record the crossing. Never switch the rule off to make the change pass.
5. When a boundary must move, write it down in an Architectural Decision Record (ADR) with the rationale, and reference it in the pull request.
6. Treat the design system as a library under the same rules. Components read colour from tokens by role, never from a raw hex value.
7. Keep the legacy corner frozen and wrapped. No new code imports it. Dependencies point one way, from old to new, so the old code stays deletable.
8. Treat monorepo or polyrepo as an organisational choice. One repository with boundaries inside fits teams that share a design system, a domain model and one release train. Separate repositories fit products that ship on their own schedules and share almost nothing, or when strict repository-level access control is a hard requirement.
9. Do not introduce micro-frontends to fix a messy codebase. They fit when separate organisations must deploy independently into one shell. Fix the missing boundary first.

## Before you say done

- Run the project's boundary lint (Nx module boundaries or Sheriff) and fix every new error.
- Search the diff for imports from `ui` into `data-access`, from modern code into legacy code, and for raw colour values in stylesheets.
- List every boundary crossing in the pull request with its ADR.

Sources

  1. Nx, Enforce Module Boundaries, documentation
  2. Sheriff, Introduction, documentation
  3. Nx, Monorepo vs Polyrepo, documentation
  4. Cam Jackson, Micro Frontends, martinfowler.com, 2019
  5. Angular, UpgradeModule, référence de l'API
  6. ADR organization, Architectural Decision Records (ADRs)
Partager cet article