L’issue s’ouvre déjà remplie avec le titre et l’adresse de 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 ?
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.
La relecture (en couleur) porte sur la source texte, pas sur l'image.Source · SVG
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.
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 ?
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èchea -> 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.
Le système modélisé est mis en avant, les systèmes externes sont atténués.Source · SVG
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.
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ère
Mermaid 12.2.0
D2 v0.9.0
PlantUML 1.2026.8
Rendu natif GitHub
Oui : issues, discussions, pull requests, wikis et fichiers Markdown
Non
Non
Rendu natif GitLab
Oui (« GitLab supports Mermaid version 11 »)
Non, sauf via Kroki activé par un administrateur
Oui sur GitLab.com, sans configuration ; en auto-hébergé, si l'administrateur l'active
Installation
Rien côté forge ; mmdc (Node.js et un navigateur) ou Kroki pour produire un fichier
Un binaire
Java (image de référence avec Temurin 21) ou un conteneur
Mise en page
ELK par défaut depuis la 12.0.0, dagre au choix
dagre, ELK et TALA, tous livrés
Graphviz (dot) pour la plupart des types (classes, composants, déploiement), pas pour les séquences
Licence
MIT
MPL-2.0
GPL par défaut, jars aussi en LGPL, ASL, BSD, EPL et MIT
Point fort
Rendu par la forge, rien à installer
Conteneurs imbriqués, choix du moteur de placement
Types UML les plus complets, séquences riches
Point faible
Mise en page peu contrôlable, rendu qui varie selon la version
Absent des forges, Kroki embarque une D2 plus ancienne
Java, pas de rendu sur GitHub
Glissez pour voir
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.
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.
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) :
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 :
La sortie attendue est HTTP 200, et contexte.svg contient les libellés du
diagramme. Un piège : curl -d @contexte.mmdsupprime 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.
Outil
Erreur provoquée
Message réel
Ce qu'il faut lire
Mermaid
-> au lieu de -->
Parse error on line 2: ... got 'MINUS'
Le jeton got 'MINUS' désigne le tiret isolé
D2
accolade jamais fermée
casse.d2:3:29: maps must be terminated with }
3:29 est la ligne et la colonne de l'accolade ouvrante
PlantUML
ligne sans : avant le libellé
Error line 6 in file: casse.puml, code de retour 200
La ligne 6 est bien la ligne fautive
Glissez pour voir
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 ?
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
⏱️--:--
0 / 6
Vérification
(0/0)
--:--
0%
0Correctes
0À revoir
0:00Temps
-Niveau
Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.