Migrer un frontend Bootstrap vers un Design System custom, sans régression ni rupture produit
4 mars 2026
Refondre une interface n’est jamais un simple sujet d’UI. Dans un produit SaaS complexe, c’est un sujet d’ingénierie, d’organisation et de responsabilité. Nous avons accompagné un acteur du secteur de la santé dans la modernisation complète de son interface. La plateforme, développée en Angular, reposait sur une ancienne version de Bootstrap. L’objectif était clair : construire un Design System sur mesure et migrer progressivement l’ensemble du frontend, sans régression fonctionnelle et sans interruption métier. Le contexte imposait une exigence forte : zéro breaking change fonctionnel.
Point de départ : une UI vieillissante, un socle Bootstrap limitant
Bootstrap est une bibliothèque UI qui fournit des composants prêts à l’emploi (boutons, modales, formulaires…), des classes utilitaires, un système de grille et un socle CSS/JS standardisé pour construire rapidement une interface cohérente.
C’est efficace pour démarrer vite, surtout quand le design n’est pas un enjeu différenciant. Mais à mesure que le produit grandit, la personnalisation devient coûteuse : on finit par surcharger les styles existants, à gérer des exceptions, et à dépendre fortement d’une version donnée. Le frontend devient plus difficile à faire évoluer sans dette visuelle et technique. La dette visuelle est souvent sous-estimée. Elle ne bloque pas immédiatement la production, mais elle ralentit chaque évolution.
Dans une logique de modernisation, la question est d’identifier jusqu’où cette base reste alignée avec le produit, son identité et son rythme d’évolution.
En effet, dans le cas du projet dont nous parlons, la logique induite par Bootstrap avait atteint ses limites :
- personnalisation difficile ;
- surcharge de styles pour adapter le rendu ;
- dette UI progressive ;
- dépendance forte à une version donnée ;
- incohérences visuelles d’une page à l’autre.
La plateforme était entièrement construite sur cette base. L’interface ne reflétait plus les standards actuels. Le produit évoluait, mais son socle visuel restait figé.
En parallèle, le client avait initié un Design System interne. Peu structuré, partiellement développé, jamais réellement intégré. La décision a donc été prise de repartir sur des bases solides.
Un Design System externalisé, versionné, décorrélé de l’application
Le Design System a été reconstruit comme une bibliothèque externe au projet principal.
Des choix structurants ont été faits :
- isolation technique ;
- versioning maîtrisé ;
- composants découplés du legacy ;
- intégration progressive dans l’application existante.
Un Design System n’est pas seulement un livrable technique, c’est un produit à part entière, avec sa propre gouvernance et son cycle de vie.
Les nouveaux composants ont été développés à partir des maquettes Figma produites par l’équipe Design du client. L’UX 2.0 était définie. Il fallait à présent l’industrialiser.
Un travail étroit entre designers et développeurs a permis de définir les règles d’intégration strictes entre composants Figma et composants Angular, afin d’éviter toute divergence d’interprétation et de garantir une implémentation fidèle aux maquettes.
Le défi ne résidait donc pas dans la création du Design System, mais dans sa cohabitation avec l’existant.
Une contrainte structurante : la rétrocompatibilité à 100 %
La plateforme fonctionne avec un système de feature flags. Tous les clients ne disposent pas des mêmes fonctionnalités. Tous ne basculent pas en même temps vers la nouvelle interface.
Il y a plusieurs conséquences à cela :
- anciens composants et nouveaux composants doivent coexister ;
- les flux de données backend ne doivent jamais être altérés ;
- aucun changement de comportement ne peut être introduit ;
- chaque composant migré doit produire strictement les mêmes résultats fonctionnels.
Dans un contexte médical, une régression n’est pas acceptable. La migration devait donc être progressive, incrémentale, contrôlée.
Ces contraintes posaient une question centrale : comment les respecter concrètement côté développement ?
Isoler le design du métier : le levier de la rétrocompatibilité
Au-delà des principes d’architecture et d’organisation, un levier déterminant dans la réussite de cette migration a été l’isolation stricte du code “design”.
Initialement, les styles étaient directement intégrés dans les composants métier. Cette approche, classique dans des applications construites avec Bootstrap, rend toute évolution visuelle compliquée et risquée : modifier un style revient souvent à impacter le comportement ou l’apparence de plusieurs écrans de manière imprévisible.
Nous avons donc engagé un travail progressif pour découpler complètement ces deux dimensions :
- extraction des styles hors des composants métier,
- centralisation des règles visuelles dans le Design System,
- remplacement progressif des implémentations Bootstrap par des composants du Design System.
Concrètement, chaque migration de composant suivait une logique simple : le comportement métier restait strictement identique, seule la couche de présentation était remplacée.
Cette séparation claire a eu plusieurs effets structurants :
- elle a permis de garantir une rétrocompatibilité fonctionnelle totale,
- elle a réduit les effets de bord lors des refactorings,
- elle a renforcé la cohérence visuelle globale,
- elle a facilité l’adoption progressive du Design System sans demander de refonte massive.
Implémenter la rétrocompatibilité : une approche incrémentale côté développement
Les contraintes de rétrocompatibilité ne peuvent pas être respectées uniquement par des règles ou des intentions, elles doivent être traduites en pratiques concrètes côté développement.
Chaque composant migré suivait un processus strict :
- identification d’un composant legacy existant
- analyse de ses comportements réels (y compris les edge cases)
- création ou adaptation de son équivalent dans le Design System
- intégration dans l’application sans modification du flux de données
- validation via tests unitaires et QA métier
Dans certains cas, anciens et nouveaux composants coexistaient temporairement, pilotés par des feature flags. Cette cohabitation permettait de sécuriser les transitions sans exposer de régression aux utilisateurs.
Le cœur de la réussite : la discipline d’ingénierie
Pour mener à bien ce projet, nous n’avons pas exploité de méthode révolutionnaire, mais avons fait preuve d’une rigueur absolue.
1. Tests unitaires systématiques
Le projet étant en Angular, chaque composant généré dispose de son fichier de test dédié généré via Angular CLI. Cette capacité a été exploitée pleinement.
La règle de base est simple : aucune merge request sans tests associés.
Chaque composant du Design System et chaque intégration dans l’application ont été couverts par des scénarios unitaires complets :
- comportements standards ;
- cas limites ;
- scénarios d’erreur ;
- compatibilité avec les données existantes.
Les pipelines CI exécutaient automatiquement l’ensemble des tests avant tout déploiement.
Ce cadre n’est pas optionnel dans un projet de migration. Il est structurant.
2. Code review obligatoire et systématique
Chaque évolution passait par une relecture par un pair pour vérifier plusieurs points :
- cohérence d’implémentation ;
- respect des guidelines ;
- détection d’effets de bord ;
- alignement avec le Design System.
Ce contrôle croisé limite les dérives individuelles et sécurise les choix techniques. Dans une migration progressive, il réduit fortement le risque cumulatif.
3. QA métier en environnement de préproduction
Une fois les tests techniques validés, l’équipe de contrôle qualité prend le relai :
- déploiement en préproduction ;
- exécution des scénarios d’acceptance ;
- vérification de la rétrocompatibilité ;
- validation des comportements métier.
Les équipes QA internes au client testaient chaque ticket selon des critères précis.
La validation ne portait pas uniquement sur l’UI, mais sur l’intégrité fonctionnelle globale.
Ce niveau d’exigence est indispensable lorsqu’on manipule des données critiques.
Une organisation produit adaptée à la double dynamique
La difficulté n’était pas uniquement technique. Elle était également (et surtout) organisationnelle.
Deux flux de travail coexistaient :
- Le Board “Features” : de nouvelles fonctionnalités développées directement avec le nouveau Design System.
- Le Board “Design System” : création des composants nécessaires à la migration et aux futures features.
La priorisation de l’ensemble de ces features à développer et à livrer devenait stratégique.
Un Product Owner impliqué et transversal pilotait les dépendances :
- identifier les composants nécessaires aux nouvelles fonctionnalités ;
- anticiper les blocs de migration ;
- arbitrer entre innovation et dette existante.
Sans cette orchestration, la migration se serait fragmentée. Le rôle du Product Owner a été déterminant pour piloter et prioriser les développements. Avec sa vision produit et stratégique, il a été la boussole du projet.
Migrer un frontend legacy vers un Design System custom ne repose pas sur une innovation isolée.
La réussite tient à :
- l’architecture choisie ;
- la séparation claire des responsabilités ;
- la rigueur des tests ;
- la qualité des revues de code ;
- la maturité produit ;
- la coordination entre UX, engineering et QA.
C’est un travail d’endurance, basé sur une méthode solide et rigoureuse.
Pour aller plus loin
La migration vers un Design System, l’industrialisation frontend, la stratégie choisie et la gestion des architectures headless sont des sujets structurants qui ont une influence directe sur la réussite d’un projet, en fonction de son contexte propre.
Le 19 mars 2026, Kaliop organise une matinée de conférences dédiées aux architectures headless, avec un focus particulier sur les défis techniques autour du frontend. Inscrivez-vous dès maintenant !
Développeur Frontend
