Les micro-frontends sont devenus l'un des patterns architecturaux les plus débattus dans le développement frontend. Les partisans disent qu'ils permettent des déploiements d'équipe indépendants et une mise à l'échelle. Les critiques disent qu'ils ajoutent une complexité inutile. Les deux ont raison — la question est quel compromis compte le plus pour votre situation spécifique.
J'ai une perspective unique sur le sujet car j'étais l'architecte principal d'une architecture micro-frontend pour la stratégie B2C d'AXA Suisse, et j'ai aussi choisi de NE PAS utiliser les micro-frontends dans des rôles ultérieurs. Les deux décisions étaient correctes dans leur contexte.
Le problème que les micro-frontends résolvent vraiment
Les micro-frontends résolvent bien un problème : l'indépendance organisationnelle. Quand vous avez plusieurs équipes qui doivent livrer des fonctionnalités pour la même application utilisateur à des rythmes différents, et que la coordination entre ces équipes est devenue un goulot d'étranglement, les micro-frontends peuvent aider.
C'est tout. Ils ne rendent pas votre application plus rapide (généralement le contraire). Ils ne rendent pas votre code plus propre. Ils ne réduisent pas la complexité. Ils échangent de la complexité technique contre de la flexibilité organisationnelle.
Chez AXA, nous avions exactement ce problème. Plusieurs équipes géraient différentes parties de l'expérience client B2C : devis d'assurance, sinistres, gestion des polices et onboarding. Chaque équipe avait sa propre cadence de sprint, ses propres priorités et son propre calendrier de releases. Un frontend monolithique signifiait qu'un bug dans le module sinistres pouvait bloquer une release du module devis. Les équipes passaient plus de temps à coordonner les déploiements qu'à développer des fonctionnalités.
Comment nous l'avons fait chez AXA
Notre approche était pragmatique, pas idéologique. Nous n'avons pas poursuivi le rêve microservices du « chaque équipe choisit son propre framework ». Nous avons standardisé sur React et TypeScript — la liberté était dans l'indépendance de déploiement, pas dans le choix technologique.
Chaque micro-frontend était son propre bundle JS déployé sur le serveur. Le code vendor était extrait dans un chunk partagé pour éviter la duplication des dépendances. Nous avons construit un outillage Rollup personnalisé qui permettait de tout releaser en une fois via AEM CMS, mais aussi de permettre aux équipes individuelles de remplacer uniquement leur bundle JS sur le serveur pour les hotfixes — sans release complète.
Un agrégateur liait les apps ensemble, et une classe de docking gérait la communication inter-apps — état partagé, contexte utilisateur et tokens. Chaque app créait automatiquement sa propre shell et pouvait décider si elle nécessitait une authentification ou fonctionnait de manière anonyme. L'équipe devis pouvait ainsi déployer indépendamment tandis que l'équipe sinistres travaillait à son propre rythme.
En plus de cela, j'ai fondé une bibliothèque de composants commune construite avec Web Components — agnostique au framework, pour que chaque équipe consomme les mêmes briques UI. Elle s'intégrait directement dans l'architecture micro-frontend : UX cohérente à travers toutes les apps, maintenue par une équipe dédiée au style guide.
// Each micro-frontend = its own JS bundle on the server
// Vendor JS is shared across all apps in a common chunk
// Rollup builds each app independently
// apps/quotes/rollup.config.js → /server/static/quotes.js
// apps/claims/rollup.config.js → /server/static/claims.js
// shared/vendor.js → /server/static/vendor.js
// Aggregator collects all apps and provides a docking class
// for cross-app communication (shared state, auth tokens)
class AppDocking {
private shared = new Map<string, unknown>();
set(key: string, value: unknown) { this.shared.set(key, value); }
get<T>(key: string): T { return this.shared.get(key) as T; }
}
// Each app auto-creates its own shell and decides
// whether it needs an access token or runs anonymously
interface AppConfig {
name: string;
entry: string; // /server/static/quotes.js
container: string; // #quotes-root
requiresAuth: boolean; // app decides this
}
// Deploy all apps at once via AEM CMS release,
// OR override individual JS on the server for hotfixes
// App X deploys → only /server/static/x.js gets replacedLes vrais coûts dont personne ne parle
Voici ce que les conférences omettent :
L'état partagé est difficile. Vraiment difficile. Quand deux micro-frontends doivent partager le contexte utilisateur, l'état du panier ou les compteurs de notifications, vous construisez essentiellement un système distribué dans le navigateur. Nous avons passé des semaines à synchroniser l'état d'authentification de manière fiable entre les modules sans conditions de course.
La cohérence UX coûte cher. Quand les modules sont déployés indépendamment, des incohérences visuelles s'installent. Le module A est livré avec des styles de boutons mis à jour tandis que le module B a encore les anciens. Nous avons résolu cela avec notre bibliothèque de guide de style basée sur les Web Components — des composants agnostiques au framework que chaque module consommait. Mais construire et maintenir cette bibliothèque était un investissement considérable.
La surcharge de performance est réelle. Chaque module apporte sa propre surcharge d'exécution. Même avec les dépendances partagées extraites dans un chunk commun, le chargement initial est plus lourd qu'une application unique. Chez AXA, notre Time to Interactive a augmenté d'environ 800ms par rapport au monolithe. Nous avons optimisé avec du lazy loading et du prefetching agressifs, mais la surcharge n'a jamais complètement disparu.
L'expérience développeur en souffre. Faire tourner l'application complète localement signifie orchestrer plusieurs serveurs de développement. Le débogage à travers les frontières des modules est pénible. Les tests d'intégration nécessitent que tous les modules soient disponibles. Nous avons construit un outillage conséquent pour rendre cela praticable, ce qui était en soi une charge de maintenance.
Quand j'ai choisi de ne pas les utiliser
Chez Migros, en construisant Bikeworld et Micasa, nous avions un problème similaire en surface : plusieurs boutiques partageant de l'infrastructure. L'instinct aurait pu être d'utiliser des micro-frontends. Mais j'ai choisi un monorepo PNPM avec Turbo à la place.
Pourquoi ? Parce que le problème organisationnel était différent. Nous avions une seule équipe qui construisait les deux boutiques, pas plusieurs équipes nécessitant des déploiements indépendants. Les boutiques partageaient un design system et de l'infrastructure mais avaient des pages produit et des flux de checkout différents. Un monorepo avec des packages partagés nous donnait la réutilisation de code sans la complexité de déploiement.
Chez Vontobel, en construisant une plateforme financière complexe unique, les micro-frontends auraient été du pur overhead. Une équipe, une cible de déploiement, un cycle de release. Une application Next.js bien structurée avec des frontières de modules claires — imposées par les règles de linting et la revue de code, pas par l'isolation à l'exécution — était la bonne réponse.
Dans une grande banque suisse, j'ai orienté les micro-frontends différemment : Webpack Module Federation avec un monorepo basé sur Turborepo pour 3 équipes. Contrairement à l'approche Rollup personnalisée d'AXA où les bundles JS résidaient sur le serveur et pouvaient être remplacés individuellement, Module Federation agrège au runtime — la shell charge les modules distants à la demande. Le monorepo nous donne un outillage partagé et des standards de code cohérents, tandis que la fédération donne à chaque équipe une indépendance totale de déploiement. Deux implémentations très différentes du même principe : des équipes qui peuvent livrer sans s'attendre mutuellement.
Le cadre de décision
Après avoir vécu avec les micro-frontends et choisi des alternatives, voici mon cadre pour déterminer quand ils ont du sens :
Utilisez les micro-frontends quand : vous avez 4+ équipes livrant à la même application, la coordination des déploiements est devenue un goulot d'étranglement mesurable (pas juste un désagrément), les équipes ont des cadences de release véritablement différentes, et vous avez la capacité d'ingénierie pour construire et maintenir l'infrastructure requise (shell app, bibliothèques partagées, outillage, pipelines CI/CD).
N'utilisez pas les micro-frontends quand : vous avez moins de 3 équipes, vous voulez utiliser différents frameworks par module (le coût UX est trop élevé), votre application a de fortes dépendances de données inter-modules, vous n'avez pas de capacité dédiée en ingénierie de plateforme, ou vous les choisissez parce qu'ils sont à la mode plutôt que parce que vous avez ressenti la douleur qu'ils résolvent.
// Alternatives that solve similar problems with less cost
// 1. Monorepo with package boundaries
// Good for: shared code, independent builds, one team
// pnpm-workspace.yaml + turborepo
// 2. Module-level code splitting in a single app
// Good for: lazy loading, team ownership areas
const AdminModule = lazy(() => import('./modules/admin'));
const QuotesModule = lazy(() => import('./modules/quotes'));
// 3. Feature flags for independent feature releases
// Good for: decoupling deployment from release
if (flags.newCheckout) {
return <NewCheckout />;
}L'architecture est une question de compromis
La meilleure architecture est la plus simple qui résout vos problèmes réels. Pas les problèmes que vous pourriez avoir dans deux ans. Pas les problèmes que l'entreprise qui a écrit cet article Medium avait. Vos problèmes, aujourd'hui.
Les micro-frontends ont résolu un vrai problème chez AXA — bundles Rollup personnalisés sur un serveur, classe de docking pour l'état partagé, déploiement individuel via AEM CMS. Dans une grande banque suisse, le même problème a reçu une solution différente : Webpack Module Federation avec agrégation runtime depuis un monorepo. Les deux fonctionnent. L'implémentation diffère car les contraintes diffèrent. Un monorepo a résolu un vrai problème chez Migros. Une application unique bien structurée a résolu un vrai problème chez Vontobel. Le pattern n'a pas changé — comprenez d'abord le problème, puis choisissez la solution la plus simple qui y répond.
Si cela ressemble à YAGNI appliqué à l'architecture, c'est exactement ça. Les principes sont les mêmes à chaque niveau d'abstraction.

