Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Diagrammes as code : pourquoi et quel outil

Par mis à jour le

Améliorer cette page

Un diagramme as code est un schéma décrit dans un fichier texte (Mermaid, D2 ou PlantUML) qu'un outil transforme en image : la source se versionne avec le code, se relit en diff (la liste des lignes ajoutées et retirées) dans une pull request (la demande de fusion d'une modification, que l'équipe relit) et se régénère quand le système change. Cette leçon s'adresse à qui sait éditer un fichier texte et ouvrir une pull request. Elle montre le même système écrit dans les trois syntaxes, aide à choisir l'outil selon la forge (GitHub ou GitLab, la plateforme qui héberge le dépôt), compare les chemins de rendu (forge, ligne de commande, Kroki), apprend à lire une erreur et à doubler le schéma d'un texte.

  • Expliquer ce qu'un diagramme en texte apporte et ce qu'il coûte.
  • Reconnaître la même vue écrite en Mermaid, en D2 et en PlantUML.
  • Choisir l'outil adapté à votre forge et à votre schéma.
  • Comparer les trois chemins de rendu et lancer un serveur Kroki épinglé.
  • Diagnostiquer une erreur de rendu et doubler le schéma d'un texte lisible.

Le modèle C4 du module précédent dit quoi dessiner ; ce module dit comment l'écrire en texte. La leçon ne redit pas C4 : elle reprend la vue contexte d'une boutique en ligne (diagramme de contexte) comme fil rouge, et mentionne sa vue conteneurs. Les trois leçons suivantes du module détaillent la syntaxe de chaque outil : Mermaid, D2 et PlantUML (facultative).

Pourquoi décrire un diagramme en texte plutôt que le dessiner ?

Section intitulée « Pourquoi décrire un diagramme en texte plutôt que le dessiner ? »

Un diagramme écrit en texte se relit ligne à ligne comme du code, alors qu'un fichier image dessiné dans un outil graphique reste opaque pour Git. Le diff est la vue de Git qui montre ce qui a été ajouté ou retiré entre deux versions : sur du texte, il est lisible ; sur une image, personne ne relit un changement de pixels. Le rendu devient un simple résultat de calcul qu'on refait à chaque modification de la source.

Une mesure le montre, faite sur une version antérieure de la même vue (avec d'autres identifiants de nœuds). On ajoute un service de paiement à une vue contexte, et Git compte deux lignes ajoutées dans la source Mermaid :

paiement["Service de paiement<br/>(système externe)"]
boutique -->|"Débite la carte (JSON/HTTPS)"| paiement

Le SVG (format d'image vectorielle, lui-même écrit en texte) que Mermaid produit par Kroki (un service de rendu, présenté plus bas) tient, lui, sur une seule ligne de plusieurs kilo-octets : git diff --no-index --stat annonce « 1 insertion(+), 1 deletion(-) » sur un bloc illisible. Avec la ligne de commande mmdc, le fichier compte une centaine de lignes, mais le diff reste noyé dans des identifiants et des coordonnées générés. La règle : on fait relire la source, jamais l'image générée.

La chaîne complète tient en quatre étapes. Regardez où se place la relecture : elle porte sur la source, avant tout rendu.

Chaîne d'un diagramme as code : une source texte .mmd ou .d2 est modifiée dans une pull request dont le diff est relu, puis rendue par la forge, une commande ou Kroki, pour donner le diagramme affiché dans la documentation.Source texte.mmd ou .d2Pull request :diff de la sourceRendu : forge,CLI ou KrokiDiagrammedans la doc
La relecture (en couleur) porte sur la source texte, pas sur l'image. Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Ce confort a deux contreparties. D'abord la mise en page est automatique : vous décrivez les éléments et les liens, le moteur place les boîtes, et vous ne contrôlez pas finement leur position. Ensuite le rendu dépend du moteur et de sa version. Mesure faite pour cette leçon : la même source conteneurs.mmd (la vue conteneurs de la boutique, voir la leçon conteneurs C4) rendue par Mermaid 11.12.3 puis par Mermaid 12.1.0 donne deux images différentes. Mermaid 12.0.0, publié le 10 septembre 2026, a fait d'ELK le moteur de mise en page par défaut des diagrammes de flux, à la place de dagre (les deux sont des algorithmes qui placent les boîtes). Regardez la forme générale : l'image de Mermaid 11 mesure environ 1580 sur 524 unités, celle de Mermaid 12 environ 1849 sur 334. La leçon Mermaid explique comment choisir le moteur.

Vue conteneurs de la boutique rendue par Mermaid 11.12.3 (moteur dagre) : un cadre Boutique en ligne contient l'interface web, l'API et la base de données, entouré des deux personnes et des deux services externes.

La même source rendue par Mermaid 12.1.0 (moteur ELK) : mêmes éléments et mêmes flèches, mais une disposition plus large et moins haute.

Les deux images disent la même chose avec une autre disposition : le texte ne fixe pas la position des boîtes. Pour un schéma qui doit être pixel-perfect, un outil de dessin reste le bon choix.

À quoi ressemble la même vue en Mermaid, en D2 et en PlantUML ?

Section intitulée « À quoi ressemble la même vue en Mermaid, en D2 et en PlantUML ? »

Les trois outils décrivent le même schéma avec des syntaxes différentes. Le fil rouge de toute la formation est une boutique en ligne ; sa vue contexte (celle de C4) compte deux personnes, le Client et le Gestionnaire de boutique, le système modélisé Boutique en ligne et deux systèmes externes, un Service de paiement et un Service de mail. Pas de base de données à ce niveau : c'est un conteneur, donc une vue plus fine.

Première version, en Mermaid (fichier contexte.mmd) :

flowchart LR
client["Client<br/>(personne)"]
gestionnaire["Gestionnaire de boutique<br/>(personne)"]
boutique["Boutique en ligne<br/>(système)"]
paiement["Service de paiement<br/>(système externe)"]
mail["Service de mail<br/>(système externe)"]
client -->|"Consulte le catalogue et commande (HTTPS)"| boutique
gestionnaire -->|"Gère le catalogue et les stocks (HTTPS)"| boutique
boutique -->|"Débite la carte (JSON/HTTPS)"| paiement
boutique -->|"Envoie les e-mails de commande (SMTP)"| mail

Ligne à ligne : flowchart LR déclare un diagramme de flux orienté de gauche à droite (LR, pour left to right). Chaque ligne suivante déclare un nœud avec un identifiant court (boutique) suivi de son libellé entre crochets et entre guillemets, où <br/> force un retour à la ligne. Les quatre dernières lignes sont les relations : --> trace une flèche, et le texte entre barres verticales |"..."| l'étiquette avec l'action et le protocole.

Deuxième version, en D2 (fichier contexte.d2) :

direction: right
client: Client {shape: person}
gestionnaire: Gestionnaire de boutique {shape: person}
boutique: Boutique en ligne
paiement: Service de paiement (externe)
mail: Service de mail (externe)
client -> boutique: Consulte le catalogue et commande (HTTPS)
gestionnaire -> boutique: Gère le catalogue et les stocks (HTTPS)
boutique -> paiement: Débite la carte (JSON/HTTPS)
boutique -> mail: Envoie les e-mails de commande (SMTP)

Un nœud D2 s'écrit identifiant: Libellé, une flèche a -> b: libellé, et la forme se règle entre accolades (shape: person dessine un bonhomme). Le langage se lit presque comme du texte courant, et un nœud peut en contenir d'autres, ce qui sert aux vues imbriquées.

Troisième version, en PlantUML (fichier contexte.puml) :

@startuml
left to right direction
actor "Client" as client
actor "Gestionnaire de boutique" as gestionnaire
rectangle "Boutique en ligne" as boutique
rectangle "Service de paiement\n(externe)" as paiement
rectangle "Service de mail\n(externe)" as mail
client --> boutique : Consulte le catalogue et commande (HTTPS)
gestionnaire --> boutique : Gère le catalogue et les stocks (HTTPS)
boutique --> paiement : Débite la carte (JSON/HTTPS)
boutique --> mail : Envoie les e-mails de commande (SMTP)
@enduml

PlantUML encadre le diagramme par @startuml et @enduml, déclare les éléments avec un type (actor, rectangle) puis un alias après as, et trace une flèche avec --> suivi de : et du libellé. C'est le plus ancien des trois et le plus riche en types de diagrammes UML.

Voici le rendu du schéma. Regardez le système modélisé, mis en avant au centre, les personnes à gauche et les systèmes externes atténués à droite, avec un verbe et un protocole sur chaque flèche.

Vue contexte de la boutique en ligne : le client et le gestionnaire de boutique utilisent la boutique en HTTPS ; la boutique débite la carte auprès d'un service de paiement externe en JSON sur HTTPS et envoie les e-mails de commande par un service de mail externe en SMTP.Consulte le catalogue etcommande (HTTPS)Gère le catalogue et les stocks(HTTPS)Débite la carte (JSON/HTTPS)Envoie les e-mails decommande (SMTP)Client(personne)Gestionnaire de boutique(personne)Boutique en ligne(système)Service de paiement(système externe)Service de mail(système externe)
Le système modélisé est mis en avant, les systèmes externes sont atténués. Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Le choix de syntaxe ne change pas le contenu du schéma, seulement la façon de l'écrire et de le rendre. Mermaid propose aussi une syntaxe dédiée à C4, C4Context, que la leçon C4 en code compare à Structurizr DSL et à C4-PlantUML.

Le bon outil dépend d'abord de l'endroit où le schéma sera lu, ensuite du besoin de mise en page. L'arbre ci-dessous se lit de haut en bas : à chaque losange, répondez par oui ou par non jusqu'à une recommandation. Premier critère : si chaque boîte doit être placée à la main, au pixel près, ce n'est plus un diagramme as code.

Arbre de décision : si chaque boîte doit être placée au pixel près, utiliser un outil de dessin ; sinon, si le schéma vit dans un README, une issue ou une pull request GitHub ou GitLab, utiliser Mermaid rendu par la forge ; sinon, pour des groupes imbriqués, D2 ; pour de l'UML détaillé ou un projet déjà en PlantUML, PlantUML ; dans tous les autres cas, Mermaid par défaut.Chaque boîte doit être placéeà la main, au pixel près ?Outil de dessin (draw.io, Excalidraw) :ce n'est plus un diagramme as codeouiLe schéma vit dans un README, une issueou une pull request GitHub ou GitLab ?nonMermaid : rendu par la forge,rien à installerouiDes groupes imbriqués : conteneurs dansun système, nœuds dans un cluster ?nonD2 : un binaire, des conteneurs,les moteurs dagre, ELK et TALAouiUML détaillé (séquence riche, déploiement)ou un projet déjà écrit en PlantUML ?nonPlantUML : Java ou un conteneur,le plus complet en UMLouiMermaid par défaut : le plus répandu ;mmdc ou Kroki pour produire l'imagenon
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Le tableau compare les trois outils sur les critères qui comptent à l'usage : rendu natif, installation, mise en page, licence. Les faits viennent des documentations officielles, relues le 2026-10-13 : Creating diagrams de GitHub, la section « Diagrams and flowcharts » de GitLab Markdown, les pages PlantUML et Kroki de l'administration GitLab, puis mermaid.js.org, d2lang.com et plantuml.com.

CritèreMermaid 12.2.0D2 v0.9.0PlantUML 1.2026.8
Rendu natif GitHubOui : issues, discussions, pull requests, wikis et fichiers MarkdownNonNon
Rendu natif GitLabOui (« GitLab supports Mermaid version 11 »)Non, sauf via Kroki activé par un administrateurOui sur GitLab.com, sans configuration ; en auto-hébergé, si l'administrateur l'active
InstallationRien côté forge ; mmdc (Node.js et un navigateur) ou Kroki pour produire un fichierUn binaireJava (image de référence avec Temurin 21) ou un conteneur
Mise en pageELK par défaut depuis la 12.0.0, dagre au choixdagre, ELK et TALA, tous livrésGraphviz (dot) pour la plupart des types (classes, composants, déploiement), pas pour les séquences
LicenceMITMPL-2.0GPL par défaut, jars aussi en LGPL, ASL, BSD, EPL et MIT
Point fortRendu par la forge, rien à installerConteneurs imbriqués, choix du moteur de placementTypes UML les plus complets, séquences riches
Point faibleMise en page peu contrôlable, rendu qui varie selon la versionAbsent des forges, Kroki embarque une D2 plus ancienneJava, pas de rendu sur GitHub

Quelques précisions sur ce tableau. Sur GitHub, un bloc mermaid qui contient le mot info affiche la version de Mermaid utilisée, utile pour savoir à quel rendu s'attendre : GitLab documente Mermaid 11, et la même source peut donc s'y afficher autrement que sous Mermaid 12. TALA, le moteur de placement de D2, est open source depuis la v0.9.0 et livré avec l'outil ; avant, il était fermé et payant pour un usage commercial. Ces rendus de forge n'ont pas été testés sur un dépôt réel pour cette leçon : ils reposent sur la lecture des documentations. Vérifiez chez vous avant de vous y fier.

Trois chemins existent, du plus simple au plus contrôlé. Regardez que la même source mène soit à un affichage immédiat par la forge, soit à un fichier image produit par une commande ou par Kroki, qu'on publie ensuite dans le site de documentation.

Une source texte .mmd, .d2 ou .puml peut suivre trois chemins : la forge l'affiche directement dans l'issue, la pull request ou le README ; une ligne de commande (mmdc, d2, plantuml) ou un serveur Kroki produisent un fichier SVG ou PNG, qui est ensuite publié dans le site de documentation.Source texte.mmd, .d2 ou .pumlForge : bloc de coderendu à l'affichageLigne de commande :mmdc, d2, plantumlServeur Kroki :POST /type/svgAffiché dans l'issue,la PR ou le READMEFichier SVG ou PNGproduit sur le poste ou en CIPublié dans le sitede documentation
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Le premier chemin, la forge, ne demande rien : elle rend le bloc de code quand la page s'affiche (voir le tableau plus haut pour ce que chaque forge comprend). Le deuxième est la ligne de commande : mmdc (mermaid-cli, qui pilote un navigateur sans fenêtre), d2 ou plantuml produisent un fichier image, sur le poste ou en intégration continue (la CI, qui rejoue des tâches automatiquement à chaque modification du dépôt). Le troisième est Kroki, un service HTTP qui accepte les trois langages. Les sites de documentation de la formation activent Mermaid de leur côté : voir MkDocs et Hugo.

Kroki (licence MIT, docs.kroki.io) transforme un texte en image pour des dizaines de langages. On lui envoie la source dans le corps d'une requête POST sur /<type>/<format>, par exemple /mermaid/svg. Un seul service sert donc les trois outils, et l'héberger vous-même évite d'envoyer vos schémas à un service public. Regardez sur le schéma qu'il se compose d'une passerelle et de conteneurs compagnons : PlantUML, D2, Graphviz et Structurizr sont intégrés à l'image principale, alors que Mermaid, BPMN et Excalidraw tournent dans des conteneurs séparés que la passerelle joint grâce à des variables d'environnement.

Architecture de Kroki : un client HTTP envoie une requête POST à la passerelle Kroki sur le port 8000, qui embarque les moteurs PlantUML, D2, Graphviz et Structurizr ; pour Mermaid, la passerelle appelle le conteneur compagnon kroki-mermaid (port 8002) désigné par KROKI_MERMAID_HOST ; BPMN et Excalidraw ont chacun leur compagnon (ports 8003 et 8004).Client HTTP(curl, forge, site de doc)Kroki, passerelle (port 8000)Conteneurs compagnonsMoteurs intégrés à l'imagekroki-mermaid(port 8002)kroki-bpmn(port 8003)kroki-excalidraw(port 8004)PlantUMLD2GraphvizStructurizrPOST /mermaid/svgKROKI_MERMAID_HOSTKROKI_BPMN_HOSTKROKI_EXCALIDRAW_HOST
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Le piège classique est donc l'image seule : yuzutech/kroki sans compagnon ne peut pas rendre Mermaid : la passerelle cherche par défaut le compagnon sur 127.0.0.1:8002 (variables KROKI_MERMAID_HOST et KROKI_MERMAID_PORT de la documentation de Kroki), où rien n'écoute. La requête sur /mermaid/svg répond alors Error 503: Connection refused: /127.0.0.1:8002 (code HTTP 503), alors que /health répond 200. Il faut deux services (deux conteneurs, des processus isolés lancés par Docker) sur un réseau commun. Voici le fichier compose.yaml joué le 2026-10-13, avec des images épinglées par digest (l'empreinte sha256 qui ne change jamais, contrairement à une étiquette mobile comme latest) :

services:
kroki:
image: yuzutech/kroki:0.33.0@sha256:a4341ac44cd2590124da7142d13fdf5d83eadc2b94c023d018a2227695a30da1
ports:
- "127.0.0.1:8000:8000"
environment:
- KROKI_MERMAID_HOST=mermaid
depends_on:
- mermaid
mermaid:
image: yuzutech/kroki-mermaid:0.33.0@sha256:2fd07c6ef9ef99e59c288f125fdb411188569237544f7db8d69935a2d7efa08d
expose:
- "8002"

Le fichier a été joué avec un seul changement : le port publié 8013 au lieu de 8000, ce dernier étant déjà pris sur le poste de test. docker compose up -d --wait fait passer les deux conteneurs à l'état « Healthy », et curl http://localhost:8000/health répond un JSON qui annonce Kroki 0.33.0, avec Mermaid 12.1.0, D2 0.7.1, PlantUML 1.2026.8 et Graphviz 14.1.3. Remarquez que Kroki 0.33.0 embarque D2 0.7.1, plus ancien que le binaire v0.9.0 : le rendu dépend encore du moteur. Si curl répond « Connection reset by peer » juste après up, la passerelle Java démarre encore : réessayez au bout de quelques secondes. Arrêtez le tout avec docker compose down.

L'appel qui fonctionne envoie le fichier tel quel :

Fenêtre de terminal
curl -s -w 'HTTP %{http_code}\n' --data-binary @contexte.mmd \
-H 'Content-Type: text/plain' http://localhost:8000/mermaid/svg -o contexte.svg

La sortie attendue est HTTP 200, et contexte.svg contient les libellés du diagramme. Un piège : curl -d @contexte.mmd supprime les retours à la ligne du fichier, et Kroki répond Error 400: SyntaxError: Parse error on line 1 parce que tout le diagramme tient désormais sur une seule ligne. Pour envoyer un fichier, c'est --data-binary.

La méthode est la même pour les trois outils : lire le numéro de ligne du message, aller à cette ligne dans la source, repérer le jeton fautif, puis ouvrir l'image produite avant de publier. Le tableau ci-dessous vient de trois erreurs provoquées exprès, parmi les plus courantes. Le détail par outil est dans les leçons Mermaid, D2 et PlantUML.

OutilErreur provoquéeMessage réelCe qu'il faut lire
Mermaid-> au lieu de -->Parse error on line 2: ... got 'MINUS'Le jeton got 'MINUS' désigne le tiret isolé
D2accolade jamais ferméecasse.d2:3:29: maps must be terminated with }3:29 est la ligne et la colonne de l'accolade ouvrante
PlantUMLligne sans : avant le libelléError line 6 in file: casse.puml, code de retour 200La ligne 6 est bien la ligne fautive

Deux nuances à connaître. PlantUML écrit quand même un casse.svg, qui est l'image d'erreur de l'outil : ne la publiez pas parce que le fichier existe, vérifiez le code de retour. Et une erreur de cible en D2 (client -> web alors que web vit dans boutique) ne produit aucun message : D2 crée un second nœud web à la racine, et seule l'ouverture de l'image le montre. Un code de retour non nul fait échouer un pipeline de CI, comme il se doit.

Comment rendre un schéma compréhensible sans l'image ?

Section intitulée « Comment rendre un schéma compréhensible sans l'image ? »

Un schéma est inaccessible à une personne qui ne le voit pas, et inutile dès que l'image ne charge pas. La parade tient en trois couches : le texte qui précède le schéma, qui dit ce qu'il faut regarder ; le texte alternatif (attribut alt) de l'image ; et, pour un schéma dense, une description longue sous l'image. La leçon Montrer plutôt qu'écrire détaille comment écrire un bon texte alternatif.

Ce qui change pour un diagramme en code tient en une phrase : seul Mermaid sait écrire un titre et une description dans le SVG, avec accTitle et accDescr (détaillés dans la leçon Mermaid). D2 et PlantUML n'écrivent ni <title> ni <desc> de schéma (PlantUML ne reprend que le title déclaré dans un diagramme de séquence), ce qui a été mesuré sur les rendus du lab : le texte alternatif se porte alors dans la page, avec l'alt de l'image et le paragraphe qui la précède.

  • Un diagramme as code est un fichier texte : il se versionne, se relit en diff et se régénère. On fait relire la source, jamais le SVG généré.
  • Contreparties : mise en page automatique et rendu qui dépend du moteur : la même source donne deux images en Mermaid 11 (dagre) et en Mermaid 12 (ELK).
  • La syntaxe change, pas le contenu : le même schéma s'écrit en Mermaid, en D2 et en PlantUML.
  • Choisir par la forge : Mermaid se rend seul sur GitHub et GitLab, PlantUML sur GitLab, D2 sur aucune des deux sans Kroki. Groupes imbriqués : D2 ; UML détaillé : PlantUML.
  • Rendre : la forge, une commande ou Kroki épinglé par digest. Mermaid sur Kroki exige un second conteneur et KROKI_MERMAID_HOST ; un fichier s'envoie avec --data-binary.
  • Erreur de rendu : lire la ligne, repérer le jeton fautif, ouvrir l'image produite. Doubler chaque schéma d'un texte avant, d'un alt et, si besoin, d'une description longue.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn