Que fait stack-diagram ?
Produit des diagrammes d'architecture de style dessin technique : de vrais logos sur des tuiles blanches, des boîtes de groupe étiquetées (comme les diagrammes VPC des fournisseurs cloud), des flèches orthogonales avec des étiquettes monospace, sur un fond de papier millimétré froid. Un fichier HTML autonome est la source de vérité ; les formats PNG / TSX / artefact en sont dérivés.
Prérequis
- Python 3.9+ (bibliothèque standard uniquement pour
fetch_icons.py,build.pyetshare.py) - Accès réseau aux sources d'icônes (svgl.app, raw.githubusercontent.com, cdn.jsdelivr.net, aws.amazon.com et d1.awsstatic.com pour les icônes AWS, services.google.com pour les icônes Google Cloud, learn.microsoft.com et arch-center.azureedge.net pour les icônes Azure, ainsi que le site ou le dépôt de la marque pour
name=URL) lors de la récupération des icônes - Playwright + Chromium pour
render_png.py:pip install playwright && python3 -m playwright install --with-deps chromium
Flux de travail
- Définir le contenu (nœuds, groupes, arêtes)
- Récupérer les icônes —
scripts/fetch_icons.py - Planifier les coordonnées — lire
references/geometry.md - Construire le HTML à partir de
assets/template.html—scripts/build.py - Générer un PNG et y jeter un œil avant de livrer
- Livrer dans le(s) format(s) demandé(s)
- Optionnellement le partager dans la galerie publique
Étape 1 — Contenu
À partir de la liste de technologies/services de l'utilisateur, décider :
- Nœuds : chaque technologie = un nœud (nom + un rôle court en minuscules comme
serveur http,base de données sqlite) - Groupes : tracer une boîte autour des éléments qui partagent un runtime, un fournisseur ou un dépôt (par exemple, une boîte de fournisseur cloud contenant une boîte de runtime ; une boîte de monorepo pour les outils). L'imbrication sur un niveau est correcte ; plus profond devient bruyant. Écrire les étiquettes de groupe dans la casse de la marque (
GitHub,npm) ; le modèle les affiche telles qu'écrites. - Arêtes, trois types :
- trait plein coloré = le flux principal de requêtes/données (un chemin continu se lit mieux)
- trait plein neutre = connexions secondaires internes
- trait pointillé neutre = relations de développement/déploiement (CI, hooks git, IaC deploy)
Si l'utilisateur n'a donné qu'une liste plate d'outils, inférer des groupes et des flux sensibles à partir de ce que sont les outils — ne demander que lorsqu'un outil est suffisamment ambigu pour que le diagramme soit faux dans les deux cas.
Étape 2 — Icônes
python3 scripts/fetch_icons.py <icons-dir> tanstack hono drizzle "betterauth:better-auth" "orpc=https://orpc.unnoq.com/logo.webp"
python3 scripts/fetch_icons.py <icons-dir> "aws:aws/AWS-Cloud-logo" "vpc:aws/vpc" "fargate:aws/fargate" "s3:aws/s3"
python3 scripts/fetch_icons.py <icons-dir> "gcp:google-cloud" "run:gcp/cloud-run" "lb:gcp/load-balancing" "sql:gcp/cloud-sql"
python3 scripts/fetch_icons.py <icons-dir> "azure:azure/Azure-A" "app:azure/app-service" "vnet:azure/vnet" "sql:azure/sql-database"
python3 scripts/fetch_icons.py <icons-dir> "k8s:kubernetes" "ing:k8s/ingress" "svc:k8s/service" "deploy:k8s/deployment" "pod:k8s/pod"
Formes de spécification : nom (nom utilisé comme slug), nom:slug (slug différent), nom=URL (URL explicite), nom:aws/<Nom> (icône AWS officielle), nom:gcp/<Produit> (icône Google Cloud officielle), nom:azure/<Nom> (icône Azure officielle), nom:k8s/<Ressource> (icône Kubernetes officielle). Le script essaie, dans cet ordre : svgl → devicon → gilbarbara/logos, écrit les fichiers plus manifest.json, et signale les icônes dont le remplissage est blanc. svgl (svgl.app) est le premier car il porte les marques officielles actuelles des marques de développement modernes (TanStack, Better Auth, Hono...). Lorsqu'un logo a des versions claire/foncée, la version claire devient <nom> (les tuiles sont blanches dans les deux thèmes) et la version foncée est enregistrée sous <nom>_dark pour les étiquettes de groupe. svgl est assorti par titre exact uniquement, donc un échec passe simplement à la suite. Son API expose également des variantes wordmark — parfois utiles pour une étiquette de groupe large, jamais pour les tuiles.
Règles plus importantes que la mécanique :
- Ne jamais recolorer un logo. Les utilisateurs le remarquent. Si un logo est blanc ou trop clair pour une tuile blanche, le placer sur une tuile foncée (classe
tile dark) au lieu de toucher à son remplissage. Le drapeauwhite_filldu manifeste est une heuristique — un remplissage blanc peut être un détail intérieur sur une marque colorée (tRPC, Ubuntu), donc jeter un coup d'œil au SVG avant d'utiliser la tuile foncée. - Marques officielles uniquement. simple-icons n'est délibérément pas une source : ses glyphes sont des redessins monochromes, et les utilisateurs les jugent incorrects à vue. Lorsque toutes les sources échouent (
FAIL), trouver le fichier officiel et le passer commenom=URL— chercher dans le dépôt du projet (rootlogo*.svg,docs/,assets/,public/) et sur son site (/logo.svg,/favicon.svg,/images/logo.svg). Certaines marques ne vivent que dans le dépôt (celle de Lefthook estlogo_sign.svgà la racine deevilmartians/lefthook). - Les concepts abstraits reçoivent des pictogrammes, pas du texte. Un nœud comme "environnement de développement", "cron", "file d'attente", "cache", ou "récepteur de webhook" n'a pas de marque — utiliser une icône de ligne Lucide via
nom:lucide/<icône>(par exempledevenv:lucide/terminal,cron:lucide/clock; parcourir lucide.dev/icons). Pas de texte dans une tuile, pas d'emoji. - Les sous-produits de fournisseur (Cloudflare D1/R2/KV...) n'ont généralement pas de logo distinct : réutiliser simplement le logo du fournisseur sur la tuile et laisser le nom du nœud porter la distinction ("Cloudflare D1" / "base de données sqlite").
- AWS utilise ses propres icônes. Chaque service en a une : la récupérer avec
nom:aws/<Nom>, lue depuis le package d'icônes officiel d'AWS au moment de l'exécution (par exemplelambda:aws/lambda,aws:aws/AWS-Cloud-logo,s3:aws/s3). Le préfixeAWS-/Amazon-est optionnel, les acronymes courants fonctionnent (s3,sqs,sns,ses,ecs,eks,ecr,elb,alb,nlb,iam,kms,msk,vpc), et un échec imprime chaque nom. Les slugsaws,amazonwebservicesetaws-*vont au même package, et ce qu'il ne contient pas déclenche unFAILau lieu de tomber sur une copie tierce. Toujours écrire le préfixeaws/pour un service : undynamodbnu passe toujours par la chaîne tierce. Garder le package et les fichiers d'icônes isolés hors des dépôts : AWS autorise les icônes dans les diagrammes, et la redistribution n'est pas confirmée. - La zone AWS suit les propres règles de dessin d'AWS. Les icônes de service portent leur propre carré et fonctionnent sur des fonds clairs et foncés, donc utiliser
tile bare: une tuile blanche ne fait que doubler le cadre. Les personnes et les nœuds génériques à l'intérieur utilisent les icônes générales d'AWS (user:aws/General-User; aussiGeneral-Users,General-Client,General-Internet,General-Server) danstile bare resavec la pairelt/dkdu modèle. Les groupes utilisent legroup awsdu modèle pour AWS Cloud (avecaws:aws/AWS-Cloud-logodans l'étiquette), plusregion,az,vpc,privateoupublicpour le reste : coins carrés, contour uniquement, étiquette à l'encre, pas de teinte de fournisseur, et une icône de 30px à l'affleurement dans le coin au lieu de celle de 14px. À l'intérieur d'un VPC, montrer les sous-réseaux publics et privés lorsque vous connaissez ou pouvez inférer en toute sécurité la division (un équilibreur de charge orienté Internet dans le public ; les serveurs d'application et les bases de données dans le privé) : un VPC plat est la première chose que les personnes AWS remarquent. Les arêtes à l'intérieur utilisent une couleur et une pointe de flèche ouverte :<path class="aws" ... marker-end="url(#open)"/>,aws dashpour le développement/déploiement, des étiquettes.elsimples, et pas de légende pour elles. Nommer les nœudsAmazon S3/AWS Fargate, pas unS3/Fargatenu ; une forme courte commeALBva dans la ligne de rôle, sous le nom complet (Elastic Load Balancing). Les noms peuvent prendre deux lignes, maisAmazon/AWSdoit rester sur la ligne du premier mot : s'il se retournerait juste après le préfixe, élargir ce nœud (left:<centerX-76>px; width:152px). - Google Cloud utilise ses propres icônes. Les récupérer avec
nom:gcp/<Produit>, lues depuis les packages officiels de Google au moment de l'exécution (par exemplerun:gcp/cloud-run,lb:gcp/load-balancing,memorystore:gcp/memorystore). Seuls les produits de base ont leur propre icône (Cloud Run, Cloud SQL, Cloud Storage, BigQuery, GKE, Compute Engine, Vertex AI...). Chaque autre produit utilise l'icône de sa catégorie, comme le guide de Google le spécifie : Cloud Load Balancing et Cloud CDN obtiennent tous deux Réseau ; Memorystore et Firestore obtiennent tous deux Bases de données. Écrire le nom du produit et le script choisit l'icône. Le préfixeCloud/Googleest optionnel, certaines formes courtes fonctionnent (vpc,iam,kms,iap,gce,gcs), et un échec imprime chaque nom.gcp/storageest la catégorie Stockage ; Cloud Storage estgcp/cloud-storage. Les slugsgcp-*etgoogle-cloud-*vont aux mêmes packages, et ce qu'ils ne contiennent pas déclenche unFAILau lieu de tomber sur une copie tierce : ces copies sont les icônes hexagonales retirées, que Google dit de ne pas utiliser. Toujours écrire le préfixegcp/pour un produit : unbigquerynu passe toujours par la chaîne tierce.gcp:google-cloudest la marque Google Cloud pour l'étiquette de groupe. Gemini et Firebase ne sont pas dans les packages : utiliser legeminietfirebasenus. Garder les packages et les fichiers d'icônes isolés hors des dépôts : Google propose les icônes pour les diagrammes et la documentation, et la redistribution n'est pas confirmée. - Les diagrammes Google Cloud gardent le style normal, avec les groupes de Google. Les propres diagrammes de Google (panneau bleu uni, cartes horizontales) ne sont délibérément pas copiés : les icônes vont sur la tuile blanche normale, et les arêtes et la légende restent comme d'habitude. Les groupes utilisent le
group gcpdu modèle pour Google Cloud (avecgcp:google-clouddans l'étiquette), plusvpc,region,subnetouzone. Un VPC est global et un sous-réseau est régional, donc placer la région à l'intérieur du VPC, jamais le VPC à l'intérieur d'une région. Les services globaux et sans serveur (un équilibreur de charge externe, Cloud Storage, Cloud Run) restent en dehors du VPC. Parce que les icônes sont partagées, toujours écrire le nom complet du produit (Cloud Load Balancing, pasLB), et élargir un nœud dont le nom se retournerait (left:<centerX-76>px; width:152px). - Azure utilise ses propres icônes Microsoft. Chaque service en a une : la récupérer avec
nom:azure/<Nom>, lue depuis le package officiel de Microsoft au moment de l'exécution (par exempleapp:azure/app-service,azure:azure/Azure-A,vault:azure/key-vault). Le préfixeAzure-/Microsoft-et un plurielssont optionnels, les formes courtes courantes fonctionnent (aks,vm,vnet,nsg,waf,blob,cosmos,redis,postgres,functions,front-door,apim,ai-search), et un échec imprime chaque nom. Les slugsazure,microsoft-azureetazure-*vont au même package, et ce qu'il ne contient pas déclenche unFAILau lieu de tomber sur une copie tierce. Toujours écrire le préfixeazure/pour un service : uncosmosnu passe toujours par la chaîne tierce. Microsoft Entra ID a un ensemble d'icônes séparé : passer son fichier officiel commename=URL. Microsoft autorise ces icônes uniquement dans les diagrammes d'architecture, les supports de formation et la documentation. Ne jamais recadrer, retourner, faire pivoter ou remodeler une icône, l'utiliser uniquement pour le service Microsoft qu'elle représente, et garder le package et les fichiers d'icônes isolés hors des dépôts. - Les diagrammes Azure gardent le style normal, avec les couleurs de groupe de Microsoft. Les propres diagrammes de Microsoft ne sont délibérément pas copiés : les icônes vont sur la tuile blanche normale, et les arêtes et la légende restent comme d'habitude. Les groupes utilisent le
group azuredu modèle pour Azure (avecazure:azure/Azure-Adans l'étiquette), plusrg,region,vnet,subnetouzone, et une étiquettevnetousubnetporte son icône (vnet:azure/vnet,subnet:azure/subnet). Un VNet appartient à une région, donc il va à l'intérieur de la région. Les services globaux comme Front Door restent en dehors de la région. App Service se trouve en dehors du VNet sauf s'il s'exécute dans un App Service Environment, et un service PaaS accessible via un point de terminaison privé peut se trouver à l'intérieur avecpoint de terminaison privécomme son rôle. Microsoft demande le nom complet du service à côté de chaque icône (Azure SQL Database, pasSQL), donc élargir un nœud dont le nom se retournerait (left:<centerX-76>px; width:152px). - Kubernetes utilise les icônes officielles de la communauté. Les récupérer avec
nom:k8s/<Ressource>, lues depuis l'ensemble d'icônes officiel kubernetes/community (par exemplepod:k8s/pod,deploy:k8s/deployment,svc:k8s/service,ing:k8s/ingress,cm:k8s/configmap,secret:k8s/secret,node:k8s/node,api:k8s/kube-apiserver). Les icônes utilisent les variantes sans étiquette pour les ressources et l'infrastructure afin de garder les glyphes propres et sans encombrement à l'échelle du diagramme, et les variantes avec étiquette pour les composants du plan de contrôle. Les noms courts courants et les pluriels fonctionnent (svc/service/services,deploy/deployment/deployments,po/pod/pods,cm/configmap/configmaps,sts/statefulset,ds/daemonset,node/nodes, etc.). Un échec imprime les noms disponibles. Les slugsk8s,kubernetes, etk8s/k8sfournissent le logo de roue Kubernetes officiel via la chaîne. - Les diagrammes Kubernetes gardent le style normal par défaut. Les icônes se trouvent sur la tuile blanche normale, ce qui les unifie avec les autres technologies de la pile (telles que NGINX, cert-manager, bases de données externes ou équilibreurs de charge cloud) et fournit une élévation et un contraste cohérents sur les fonds de papier millimétré. Pour les glyphes autonomes minimaux,
tile bareest également pris en charge. Les groupes utilisent les groupes standard (cluster,namespace,node,pod). Créditer l'ensemble d'icônes Kubernetes dans le pied de page du diagramme. - Les règles d'un fournisseur couvrent uniquement sa propre zone. Les règles AWS, Google Cloud, Azure et Kubernetes s'appliquent uniquement à l'intérieur du groupe de ce fournisseur, même si le diagramme ne montre rien d'autre. Tout ce qui se trouve à l'extérieur, comme un utilisateur à côté ou une arête qui le traverse, conserve les tuiles, groupes, arêtes et légende normaux.
- Nœuds non-marques (utilisateur, navigateur, internet, appareils, serveur nu) : copier un glyphe depuis
assets/generic/dans le répertoire des icônes sous le nom du nœud, ou utilisernom:lucide/<icône>— ne pas utiliser d'emoji. Ce ne sont pas des logos de marque, donc les teinter à la couleur d'encre du diagramme est acceptable (le script de récupération le fait automatiquement pour Lucide). - Les icônes d'étiquette de groupe sont rendues à 14 px — elles ont besoin d'un glyphe carré. Les wordmarks et les compositions larges deviennent flous à cette taille ; si l'icône principale est un wordmark, récupérer l'icône carrée de la marque séparément pour l'étiquette (svgl l'a généralement ; sinon le fichier d'icône ou de favicon du projet lui-même).
- Les étiquettes de groupe se trouvent sur la teinte du groupe, pas sur une tuile blanche, donc dans le thème foncé, une marque avec des parties noires y disparaît. Si
fetch_icons.pya enregistré<nom>_dark, utiliser la pairelt/dkdu modèle dans l'étiquette ; s'il n'y a pas de variante foncée et que la marque a des parties noires, ajouter la classeplateà l'étiquette