Chaque projet a besoin de configuration, et vous avez trois options principales : JSON, YAML ou TOML. J'ai utilisé les trois abondamment, et chacun me rend fou de manière différente. Voici mon avis honnête sur quand utiliser lequel.
JSON : Le soldat universel
Vous connaissez déjà JSON. Il est partout. Chaque langage sait le parser. Mais soyons honnêtes sur ses faiblesses en tant que fichier de config :
- Pas de commentaires. Vous ne pouvez littéralement pas expliquer ce que fait un paramètre. C'est complètement absurde pour un fichier de configuration.
- Pas de virgule finale. Ajoutez une ligne à la fin, oubliez la virgule sur la ligne précédente — et votre config est cassée.
- Des guillemets partout. Chaque clé nécessite des guillemets doubles :
{"port": 8080}au lieu de simplementport: 8080.
Malgré tout cela, JSON est utilisé pour la configuration par npm (package.json), TypeScript (tsconfig.json), VS Code (settings.json) et plus encore. La raison ? Zéro ambiguïté. JSON est si strict qu'il n'y a qu'une seule façon de l'interpréter.
YAML : Beau mais dangereux
YAML est magnifique. Propre, minimal, lisible par les humains. Mais il a quelques pièges notoires :
C'est le « problème de la Norvège » que j'ai mentionné dans l'article YAML. YAML 1.1 traite NO, YES, ON, OFF comme des booléens. C'est corrigé dans YAML 1.2, mais beaucoup de parsers utilisent encore le comportement 1.1 par défaut.
Ensuite il y a la sensibilité à l'indentation. Un seul espace mal placé peut complètement changer la signification de votre fichier — et le message d'erreur sera terrible.
Cela dit, YAML est le standard pour Docker Compose, Kubernetes, GitHub Actions et Ansible. Si vous êtes dans le domaine DevOps/cloud, la maîtrise de YAML est obligatoire.
TOML : Le spécialiste de la configuration
TOML (Tom's Obvious Minimal Language) a été conçu spécifiquement pour la configuration. Il vise à être évident — ce qui signifie qu'il n'y a (presque) aucun moyen de mal lire un fichier TOML.
Voici à quoi ressemble une config TOML :
Ce que TOML fait vraiment bien : types natifs date/heure (created = 2026-03-08T10:30:00Z), pas de problèmes d'indentation, commentaires avec #, et une syntaxe qu'il est vraiment difficile de rater.
L'inconvénient ? Les structures profondément imbriquées deviennent verbeuses. TOML est excellent pour les configs plutôt plates, mais si vous avez besoin de cinq niveaux d'imbrication, YAML ou JSON pourraient être plus lisibles.
TOML est utilisé par Rust (Cargo.toml), Python (pyproject.toml), Hugo et un nombre croissant d'outils.
Mes recommandations
| Scénario | Choix | Pourquoi |
| Config générée par machine | JSON | Le plus strict et compatible |
| DevOps/infrastructure | YAML | L'écosystème l'exige |
| Configuration d'app | TOML | Commentaires + ambiguïté minimale |
| Paramètres clé-valeur simples | TOML | Le plus propre pour les configs plates |
| Structures imbriquées complexes | YAML | Meilleure syntaxe imbriquée |
En résumé
La même config dans les trois formats
Voir les mêmes données dans les trois formats met vraiment en évidence les différences. Voici une configuration d'application simple :
JSON :
YAML :
TOML :
Remarquez comment JSON nécessite tous ces guillemets et accolades, YAML est le plus concis mais dépend de l'indentation, et TOML trouve un juste milieu avec des en-têtes de section explicites et aucune dépendance à l'indentation.
Erreurs courantes dans les fichiers de config
YAML : Conversion de type accidentelle. Au-delà du problème de la Norvège, YAML interprète aussi 3.10 comme le nombre 3.1 (en supprimant le zéro final), et 1_000 comme 1000. Si vos valeurs de config sont des chaînes de version comme 3.10, mettez-les toujours entre guillemets : version: "3.10".
JSON : Oublier que l'ordre n'a pas d'importance. Les objets JSON sont non ordonnés par spécification. Si votre traitement de config dépend de l'ordre des clés, vous construisez sur une base fragile. Certains parsers préservent l'ordre d'insertion, d'autres non.
TOML : Confusion avec les tableaux de tables. TOML utilise [[doubles.crochets]] pour les tableaux de tables, ce qui déroute les débutants. Voici comment définir plusieurs serveurs :
Configs spécifiques à l'environnement
Un domaine où les trois formats peinent est la gestion des surcharges spécifiques à l'environnement (dev vs staging vs production). Les solutions courantes incluent :
- Fichiers multiples :
config.base.yaml+config.production.yamlavec fusion profonde - Interpolation de variables d'environnement : Certains outils YAML supportent la syntaxe
${DB_HOST}, mais ce n'est pas standard - Outils externes : Doppler, HashiCorp Vault ou services de config cloud-native
Personnellement, je penche pour une approche simple : un fichier de config avec des valeurs par défaut sensées, et des variables d'environnement pour tout ce qui change entre les environnements. Les trois formats peuvent lire les variables d'environnement au niveau de l'application, donc le format de config lui-même n'a pas besoin de supporter l'interpolation.
Popularité des formats par écosystème
| Écosystème | Format principal | Exemples notables |
| JavaScript/Node.js | JSON | package.json, tsconfig.json, .eslintrc.json |
| Python | TOML | pyproject.toml, Cargo.toml (Rust) |
| DevOps/Cloud | YAML | docker-compose.yml, manifestes k8s, GitHub Actions |
| Go | TOML/YAML | Les deux largement utilisés, pas de standard unique |
| .NET | JSON | appsettings.json (a remplacé web.config basé sur XML) |
En résumé
Il n'y a pas de réponse unique. Utilisez JSON quand vous avez besoin d'une compatibilité maximale. Utilisez YAML quand l'écosystème l'exige (Kubernetes ne va pas commencer à accepter du TOML). Utilisez TOML quand vous voulez des commentaires et un minimum de surprises.
JSONC et JSON5 : JSON avec des roulettes
D'accord, on a bien critiqué JSON pour ne pas supporter les commentaires et les virgules finales. Mais voici ce que personne ne vous dit : il existe en fait des variantes de JSON qui corrigent ces irritations, et vous en avez probablement utilisé une sans même vous en rendre compte.
D'abord : JSONC (JSON with Comments). Si vous avez déjà ouvert un tsconfig.json et pensé « attends, il y a des commentaires là-dedans... je croyais que JSON n'autorisait pas les commentaires ? » — oui, c'est du JSONC. C'est essentiellement du JSON mais vous pouvez utiliser des commentaires sur une ligne avec // et des commentaires de bloc avec /* */. VS Code utilise JSONC pour ses fichiers settings.json, launch.json et keybindings.json. Le tsconfig.json de TypeScript est aussi techniquement du JSONC, pas du JSON strict.
Voici à quoi ressemble JSONC :
Ensuite il y a JSON5, qui va encore plus loin. JSON5 assouplit plusieurs des règles les plus strictes de JSON :
- Chaînes entre guillemets simples :
{'name': 'Sarah'}— enfin ! - Virgules finales :
{"a": 1, "b": 2,}— plus de bruit dans les diffs - Clés sans guillemets (si ce sont des identifiants valides) :
{name: "Sarah"} - Nombres hexadécimaux :
0xFF - Chaînes multi-lignes avec continuation par backslash
Infinity,-InfinityetNaNcomme nombres valides
JSON5 est excellent pour les fichiers de config où les humains sont le public principal. Certains outils le supportent nativement — par exemple, le .babelrc de Babel peut être du JSON5. Mais n'utilisez pas JSON5 pour les réponses d'API ou l'échange de données. L'intérêt du JSON strict est que tout le monde s'accorde sur le format. JSON5 est pour les humains, pas pour les machines.
Ma règle : si un outil supporte JSONC ou JSON5, utilisez-le. Il n'y a littéralement aucun inconvénient à avoir des commentaires dans vos fichiers de config. Mais si vous écrivez une bibliothèque qui lit de la config, supportez d'abord le JSON standard et JSONC/JSON5 comme extras optionnels.
Ancres et alias YAML : Config DRY
Voici la vraie fonctionnalité tueuse de YAML que beaucoup de développeurs ne découvrent jamais : les ancres et alias. Ils vous permettent de définir un bloc de config une fois et de le réutiliser partout. En gros, DRY (Don't Repeat Yourself) pour les fichiers de config.
Une ancre est marquée avec &nom et un alias la référence avec *nom. Voici un exemple pratique avec Docker Compose :
Vous voyez ce qui s'est passé ? Nous avons défini les paramètres communs une fois avec &common et les avons intégrés dans trois services avec <<: *common. Sans ancres, vous copieriez-colleriez cette politique de redémarrage et cette config de logging dans chaque service. Et quand vous devez changer la rotation des logs ? Un seul endroit au lieu de douze.
Vous pouvez aussi utiliser les ancres pour des valeurs plus simples — pas seulement pour des maps :
Maintenant, les pièges. La clé de fusion << qui rend les ancres vraiment puissantes ? Elle ne fait pas réellement partie de la spécification YAML 1.2. C'était une extension de type YAML 1.1, et bien que la plupart des parsers populaires la supportent encore, elle n'est techniquement pas standard. Donc si vous utilisez un parser YAML 1.2 strict, les clés de fusion pourraient ne pas fonctionner.
De plus, les ancres ne fonctionnent qu'au sein d'un seul fichier. Vous ne pouvez pas référencer une ancre définie dans un autre fichier YAML. Et les messages d'erreur quand vous vous trompez de nom d'alias ? Généralement quelque chose comme « undefined alias » sans aucun contexte sur où l'ancre était censée être. Du YAML classique.
TOML en profondeur : Fonctionnalités avancées
La plupart des gens connaissent les bases de TOML — sections avec [crochets], paires clé-valeur, commentaires avec #. Mais TOML a des fonctionnalités vraiment cool qui ne reçoivent pas assez d'attention. Laissez-moi vous les présenter.
Les clés pointées permettent de définir des structures imbriquées sans en-têtes de section :
C'est pratique quand vous n'avez que quelques valeurs imbriquées et ne voulez pas créer une section entière pour elles.
Les tables inline offrent une syntaxe compacte à la JSON pour les petits objets :
Utilisez les tables inline avec parcimonie cependant — elles ne peuvent pas s'étendre sur plusieurs lignes, et elles deviennent illisibles rapidement si vous y mettez trop de choses.
Les chaînes multi-lignes existent en deux variantes, et c'est là que TOML devient étonnamment réfléchi :
La chaîne basique entre triples guillemets (""") traite les séquences d'échappement, tandis que la version littérale (''') traite tout comme du texte brut. C'est parfait pour les expressions régulières ou les chemins de fichiers Windows où vous ne voulez pas que les backslashes soient interprétés comme des échappements.
Les types natifs date/heure sont quelque chose que ni JSON ni YAML ne gère aussi proprement :
Ce sont des types de première classe en TOML, pas des chaînes qui prétendent être des dates. Votre parser TOML vous donnera de vrais objets date/heure, pas des chaînes que vous devez parser vous-même.
Pourquoi Cargo de Rust a-t-il choisi TOML ? Parce que les configs de Cargo sont exactement le cas idéal pour TOML : modérément imbriquées, éditées par des humains, ont besoin de commentaires, et bénéficient d'un typage strict. Vous ne voulez pas que vos versions de dépendances soient silencieusement interprétées comme des flottants (je te regarde, YAML).
Considérations de sécurité
D'accord, c'est la section où les choses deviennent un peu effrayantes. Si vous chargez des fichiers de config depuis des sources non fiables — ou même si vous pensez que non — vous devez connaître les attaques de désérialisation.
L'exemple type est le yaml.load() de PyYAML. Dans les anciennes versions, cette fonction d'apparence innocente pouvait exécuter du code Python arbitraire intégré dans un fichier YAML. Je ne plaisante pas. Regardez ça :
Si quelqu'un glisse ça dans une config YAML et que votre app Python le charge avec yaml.load() au lieu de yaml.safe_load(), ça exécutera littéralement cette commande système. Tout supprimer. Installer une porte dérobée. Ce que l'attaquant veut.
La solution est très simple — utilisez toujours yaml.safe_load() en Python :
La documentation de PyYAML met maintenant en garde, et les versions récentes affichent un avertissement de dépréciation si vous utilisez yaml.load() sans spécifier un Loader. Mais il y a encore d'innombrables tutoriels et réponses Stack Overflow montrant la version non sécurisée. C'est une mine terrestre cachée en plein jour.
Ensuite il y a l'attaque « billion laughs » (aussi appelée bombe XML, mais ça marche aussi avec YAML). L'idée est l'expansion récursive — vous définissez des entités qui référencent d'autres entités, créant une croissance exponentielle :
Chaque niveau multiplie les données par 5, donc au niveau 8 ou 9, vous regardez des gigaoctets de données à partir de quelques lignes de YAML. La plupart des parsers YAML modernes ont des limites de profondeur et d'expansion pour empêcher ça, mais ça vaut le coup de savoir.
JSON est intrinsèquement plus sûr parce qu'il n'a aucune sémantique d'exécution. Il n'y a aucun moyen d'intégrer du code, pas de constructeurs de type, pas d'expansion d'entités. Un parser JSON lit simplement des données — chaînes, nombres, booléens, tableaux et objets. C'est tout. C'est l'un des avantages sous-estimés de la simplicité de JSON. Quand la sécurité compte, le manque de fonctionnalités de JSON est en fait une fonctionnalité.
TOML est aussi assez sûr — il n'a pas de capacités d'exécution de code ni d'expansion récursive. Mais il est moins éprouvé que les parsers JSON, alors gardez vos bibliothèques TOML à jour.
En résumé : si vous acceptez des fichiers de config d'utilisateurs ou de sources externes, JSON est le choix le plus sûr. Si vous devez utiliser YAML, utilisez toujours les fonctions de chargement sécurisé et envisagez d'exécuter un linter YAML pour détecter les constructions suspectes.
Exemples réels de fichiers de configuration
La théorie c'est bien, mais regardons de vrais fichiers de config que vous rencontrerez dans la nature. J'ai annoté chacun pour mettre en évidence les motifs spécifiques au format.
Workflow GitHub Actions (YAML) :
C'est là que YAML brille vraiment. La syntaxe de workflow GitHub Actions serait pénible en JSON — toutes ces listes imbriquées et la structure basée sur l'indentation s'adapte naturellement à YAML. Vous pouvez aussi voir comment les commentaires aident à expliquer la stratégie de matrice.
Cargo.toml de Rust (TOML) :
Remarquez comment le manifeste Cargo utilise des tables inline pour les dépendances avec des features. La syntaxe [[bin]] avec doubles crochets définit un tableau de tables — chaque entrée [[bin]] ajoute une autre cible binaire. TOML garde ça plat et lisible sans jeux d'indentation.
package.json (JSON) :
Le classique. Pas de commentaires, plein de guillemets, mais tous les outils de la planète peuvent le lire. Ce qui fait fonctionner package.json malgré les limitations de JSON, c'est que le schéma est si connu — vous n'avez pas besoin de commentaires pour expliquer ce que fait scripts.build parce que chaque développeur JavaScript le sait déjà.
.prettierrc (JSON) :
Config simple de type clé-valeur plate. Honnêtement, ce serait légèrement plus agréable en TOML (commentaires !) ou même en JSONC, et Prettier supporte d'autres formats. Mais JSON est le défaut, et pour quelque chose d'aussi simple, ça ne change pas grand-chose.
Migration entre formats
Vous avez donc décidé que le format de config de votre projet était une erreur et vous voulez changer. Ou peut-être que vous importez de la config d'un outil qui utilise un format différent. Dans tous les cas, vous devez convertir entre TOML, YAML et JSON. Je vous le dis, ce n'est pas toujours aussi fluide qu'on l'espère.
Outils de conversion :
- yq — Le couteau suisse pour YAML. Peut convertir entre YAML, JSON, TOML et XML.
yq -o=json config.yamlvous donne la sortie JSON. C'est commejqmais pour YAML. - toml-cli et taplo — Processeurs TOML en ligne de commande. Taplo est particulièrement bon pour le formatage et la validation TOML.
- One-liners Python — En cas d'urgence,
python -c "import yaml, json, sys; print(json.dumps(yaml.safe_load(sys.stdin), indent=2))" < config.yamlconvertit YAML en JSON. Pas élégant, mais ça marche. - Convertisseurs en ligne — Pour des conversions ponctuelles rapides, nos formateurs peuvent aider. Collez votre config dans le formateur approprié, nettoyez-la et réécrivez-la manuellement dans le format cible.
Quand migrer :
- Votre équipe fait constamment des erreurs d'indentation YAML dans les configs CI ? Peut-être que passer à TOML réduit ces maux de tête.
- Vous avez besoin de commentaires dans un fichier de config JSON ? Envisagez de migrer vers JSONC (si l'outil le supporte) ou TOML.
- Vous construisez un nouveau projet Rust/Python et l'écosystème attend du TOML ? Ne luttez pas — optez pour TOML.
Pièges courants lors de la migration :
Le parsing implicite de dates de YAML va vous mordre. Si vous avez une valeur YAML comme release: 2024-03-08, YAML l'interprète comme un objet date, pas une chaîne. Convertissez ça en JSON et vous pourriez obtenir "release": "2024-03-08T00:00:00Z" ou "release": "2024-03-08" selon votre convertisseur. Testez toujours votre sortie.
Le typage strict de TOML signifie que vous ne pouvez pas avoir de tableaux de types mixtes. En JSON et YAML, [1, "two", true] est parfaitement valide. En TOML, chaque élément d'un tableau doit être du même type. Si vos données source ont des tableaux mixtes, vous devrez restructurer.
Et voici le gros problème : les commentaires sont perdus. JSON ne supporte pas les commentaires, donc si vous convertissez de TOML ou YAML vers JSON, tous vos commentaires soigneusement écrits disparaissent. Dans l'autre sens (JSON vers YAML/TOML), vous voudrez ajouter manuellement des commentaires pour expliquer les paramètres non évidents, parce que la version JSON ne les avait certainement pas.
Encore une chose — les ancres et alias YAML n'ont pas d'équivalents en JSON ou TOML. Si votre config YAML repose sur des ancres pour une config DRY, la conversion vers un autre format signifie que vous devrez manuellement dupliquer ces blocs partagés. Cela peut représenter une expansion significative de la taille du fichier pour les configs complexes.
Essayez par vous-même
Quel que soit le format que vous choisissez, garder vos configs bien formatées les rend plus faciles à examiner et à déboguer. Notre TOML Formatter nettoie les fichiers TOML désordonnés instantanément. Le YAML Formatter corrige les problèmes d'indentation avant qu'ils ne causent des problèmes. Et le JSON Formatter rend même les configs JSON profondément imbriquées lisibles d'un coup d'œil.