Passer au contenu principal

developer-tools

YAML vs JSON vs TOML : Quand Utiliser Quel Format de Configuration

robinhood-projects14 min de lecture

Visionneuse, Formateur et Éditeur JSON

Visualisez, modifiez et formatez du JSON dans un arbre interactif en direct. Édition inline des valeurs, renommage des clés, ajout/suppression de nœuds, prise en charge des commentaires JSONC et export en un clic — entièrement dans votre navigateur.

Utiliser l'outil →

Visionneuse CSV & Tableau Intelligent

Ouvrez un CSV comme tableau interactif : triez les colonnes, filtrez les lignes, modifiez les cellules et exportez en CSV, XLS ou XLSX. Entièrement dans le navigateur, sans inscription.

Utiliser l'outil →

YAML vs JSON vs TOML : Quand Utiliser Quel Format de Configuration

Tout projet finit par avoir un problème de configuration. Vous devez stocker des identifiants de base de données, définir des environnements de déploiement, décrire un pipeline CI ou connecter des dépendances — et quelqu'un doit choisir un format. JSON ? YAML ? TOML ? Le choix semble arbitraire jusqu'à ce qu'il vous morde.

Les fichiers Docker Compose sont en YAML. package.json est en JSON. Le manifeste de dépendances de Rust (Cargo.toml) est en TOML. Le packaging Python (pyproject.toml) est en TOML. Les workflows GitHub Actions sont en YAML. Ce n'est pas aléatoire — chaque format a remporté la bataille d'adoption dans son domaine pour des raisons spécifiques. Comprendre ces raisons vous permet de faire un choix délibéré au lieu de prendre par défaut « ce que le template utilisait. »

Cet article est un guide de décision. À la fin, vous connaîtrez les vrais compromis de chaque format, vous verrez les footguns exacts de YAML qui ont causé des incidents en production, et vous aurez un cadre clair pour choisir.


L'Ancêtre Commun : Les Fichiers INI

Avant de plonger dans les contendants modernes, il vaut la peine de passer trente secondes sur les fichiers INI — le format auquel les trois réagissent, en un sens.

Les fichiers INI ressemblent à ceci :

[database]
host = localhost
port = 5432
name = mydb
 
[server]
port = 8080
debug = true

Simple, lisible par l'humain, supporte les sections, supporte les commentaires. Les problèmes sont tout aussi simples : pas de spec standard (chaque parser interprète les cas limites différemment), pas de structures imbriquées au-delà d'un niveau, pas de tableaux, pas de types explicites. Tout est une chaîne de caractères sauf si votre application décide autrement.

INI était bien pour php.ini en 1997. Ce n'est pas bien pour décrire un déploiement Kubernetes en 2026. Mais il a identifié les bons objectifs — l'édition humaine et les commentaires — que les formats modernes ont soit hérités, soit abandonnés.


JSON : La Lingua Franca des Données

JSON (JavaScript Object Notation) a été standardisé au début des années 2000 et est devenu le format wire dominant pour les APIs. Sa force vient de ses contraintes.

Ce que JSON fait bien

JSON a exactement six types de valeur : chaîne, nombre, booléen, null, tableau et objet. La spec est sans ambiguïté. Tout parser JSON conforme analysera le même document de façon identique. Pas de surprises.

{
  "database": {
    "host": "localhost",
    "port": 5432,
    "ssl": true
  },
  "allowed_origins": ["https://example.com", "https://api.example.com"],
  "timeout_ms": null
}

Le type de port est sans ambiguïté un nombre. ssl est sans ambiguïté un booléen. allowed_origins est sans ambiguïté un tableau de chaînes. Un parser JSON ne peut pas mal interpréter ceci.

JSON est aussi omniprésent. Chaque langage a un parser JSON en bibliothèque standard. Les navigateurs le parsent nativement. Des bases de données comme PostgreSQL ont des colonnes JSON natives. C'est le format du plus petit dénominateur commun pour l'échange de données entre systèmes qui ne partagent pas de runtime.

Ce que JSON rate pour la configuration

JSON n'a pas de syntaxe pour les commentaires. C'est une décision de conception délibérée de Douglas Crockford (le créateur de JSON), au motif que les commentaires dans les formats de données encouragent les gens à y mettre des directives d'analyse, ce qui corrompt la portabilité du format.

C'est un bon principe pour les réponses d'API. C'est un problème sérieux pour les fichiers de configuration. Les fichiers de configuration ont besoin de commentaires. Vous devez expliquer pourquoi timeout_ms est 30000 et pas 10000. Vous devez marquer quels champs peuvent être changés en toute sécurité. Vous devez laisser une note qui dit « ne pas mettre ceci au-dessus de 100 en staging. »

Les contournements sont tous mauvais. Certaines équipes utilisent des champs "_comment". Certaines utilisent JSON5 (un superset avec des commentaires) et espèrent que leurs outils le gèrent. Certaines utilisent JSONC (JSON avec Commentaires, popularisé par le settings.json de VS Code). Aucun de ces n'est du JSON standard.

JSON est aussi verbeux pour la configuration. Les virgules finales ne sont pas autorisées, ce qui cause des erreurs de syntaxe constantes lors de la réorganisation des champs. Chaque clé de chaîne nécessite des guillemets doubles. Il n'y a pas de syntaxe de chaîne multiligne — une longue commande shell doit être échappée sur une seule ligne.

JSON appartient à : les réponses d'API, l'échange de données entre services, les manifestes de packages principalement écrits par les machines (package.json, composer.json), et partout où vous avez besoin d'une cohérence de parsing garantie entre des systèmes hétérogènes.

Vous pouvez valider du JSON en ligne pour attraper les erreurs de syntaxe avant qu'elles n'atteignent votre application — ce qui compte plus que vous ne le pensez, car une seule virgule manquante ou un crochet en trop cassera entièrement un parser JSON.


YAML : Puissance et Péril

YAML (YAML Ain't Markup Language) a été conçu pour être l'alternative conviviale pour l'humain à XML. Il est expressif, lisible et largement utilisé dans les outils DevOps. C'est aussi le format de configuration le plus dangereux en usage courant.

Ce que YAML fait bien

YAML permet les commentaires (#). Il infère les types à partir des valeurs sans guillemets, vous pouvez donc écrire port: 5432 au lieu de "port": 5432. Il supporte les chaînes multilignes avec une syntaxe propre de type heredoc. Il est concis : l'indentation remplace les accolades et les crochets.

database:
  host: localhost
  port: 5432
  ssl: true
 
allowed_origins:
  - https://example.com
  - https://api.example.com
 
# C'est un commentaire expliquant pourquoi le timeout est élevé
timeout_ms: 30000

Pour les configurations CI/CD — GitHub Actions, GitLab CI, CircleCI — la capacité de YAML à exprimer des structures imbriquées proprement, avec des commentaires, est genuinement utile. Un fichier de workflow GitHub Actions couvre souvent des centaines de lignes avec des conditions imbriquées, des stratégies de matrix et des blocs de variables d'environnement. JSON serait illisible. TOML serait inconfortable pour des structures profondément imbriquées.

Les footguns de YAML

L'inférence de type de YAML est là où les choses tournent mal. Le parser regarde les valeurs sans guillemets et décide de leur type. Les décisions qu'il prend ne sont pas toujours celles que vous attendez.

Le Problème de Norvège. Dans YAML 1.1 (qui est ce que la plupart des parsers implémentent — pas YAML 1.2), un simple NO est parsé comme le booléen false. De même pour no, No, n, N, false, False, FALSE, off, Off et OFF. Une liste de codes pays ISO 3166-1 inclut NO pour la Norvège. Un fichier de configuration avec une liste de codes pays transformera silencieusement la Norvège en false.

# YAML 1.1 — ce que le parser voit réellement
country: NO        # → false (booléen)
enabled: yes       # → true (booléen)
mode: on           # → true (booléen)
debug: off         # → false (booléen)

La correction est de mettre des guillemets à tout ce qui doit être une chaîne : country: "NO". Mais tout l'attrait de YAML est qu'on n'a pas besoin de mettre des guillemets. Exiger des guillemets pour éviter les surprises érode l'avantage de lisibilité du format.

Entiers octaux. Dans YAML 1.1, un nombre commençant par 0 est traité comme octal. Les permissions de fichiers sont couramment écrites en octal : chmod: 0755. Un parser YAML lit 0755 comme le nombre décimal 493, pas 755. Cela a cassé de vrais scripts de déploiement.

# YAML 1.1 — interprétation octale
file_mode: 0755    # → 493 (équivalent décimal de l'octal 0755)

Ambiguïté des chaînes multilignes. YAML offre plusieurs syntaxes de chaînes multilignes — bloc littéral (|), bloc replié (>), et en ligne. Elles se comportent différemment par rapport aux sauts de ligne, aux espaces en fin de ligne et à l'indentation. Utiliser la mauvaise produit silencieusement la mauvaise chaîne.

# Bloc littéral — préserve les sauts de ligne
command: |
  npm install
  npm run build
 
# Bloc replié — les sauts de ligne deviennent des espaces (utile pour les longs textes)
description: >
  C'est une longue description qui sera
  repliée en une seule ligne avec des espaces.

Tabulations vs espaces. YAML n'autorise pas les caractères de tabulation pour l'indentation. Un éditeur qui insère silencieusement des tabulations produira une erreur de parsing — ou pire, un parsing différent selon la configuration de la tabulation.

YAML 1.2 a corrigé beaucoup de ces problèmes (y compris la liste des valeurs booléennes), mais la plupart des outils implémentent encore la 1.1. Quand vous utilisez YAML, vous écrivez pour le parser que votre chaîne d'outils se trouve avoir, qui peut ou non correspondre à vos hypothèses.


TOML : Conçu pour la Configuration

TOML (Tom's Obvious Minimal Language) a été créé en 2013 par Tom Preston-Werner (co-fondateur de GitHub) spécifiquement pour être un format de fichier de configuration que les humains peuvent écrire et les machines parser sans ambiguïté.

Ce que TOML fait bien

TOML a des types explicites et non ambigus. Une chaîne est toujours entre guillemets. Un nombre est toujours un nombre. Un booléen est toujours true ou false (minuscules, sans alias). Il n'y a pas d'inférence de type à partir de valeurs sans guillemets, donc pas de Problème de Norvège.

[database]
host = "localhost"
port = 5432
ssl = true
 
allowed_origins = [
  "https://example.com",
  "https://api.example.com",
]
 
# C'est un commentaire expliquant pourquoi le timeout est élevé
timeout_ms = 30000

TOML a un support de première classe pour les dates et heures (publishedAt = 2026-04-04), que JSON et YAML laissent comme des chaînes que les applications parsent elles-mêmes.

Les en-têtes de section ([database], [[servers]]) sont explicites et lisibles. Les clés avec des points (database.host = "localhost") vous permettent d'exprimer des valeurs imbriquées en ligne. Le tableau de tables ([[servers]]) vous donne une syntaxe propre de liste d'objets.

[[servers]]
name = "production"
host = "prod.example.com"
port = 443
 
[[servers]]
name = "staging"
host = "staging.example.com"
port = 443

La spec TOML est précise et versionnée. Chaque parser TOML conforme produit le même résultat pour la même entrée.

Où TOML est insuffisant

TOML fonctionne bien pour une imbrication faible à modérée. Pour des structures profondément imbriquées — du genre qui apparaît dans les manifestes Kubernetes ou les playbooks Ansible — la syntaxe des en-têtes de section devient répétitive. L'imbrication basée sur l'indentation de YAML s'adapte plus naturellement à six ou sept niveaux de profondeur.

TOML a aussi un support d'outils plus faible que JSON ou YAML. La plupart des langages ont d'excellentes bibliothèques TOML, mais le support des éditeurs (coloration syntaxique, validation, autocomplétion) est moins cohérent que celui de JSON.


Tableau Comparatif

FonctionnalitéJSONYAMLTOMLINI
CommentairesNonOui (#)Oui (#)Oui (; ou #)
Types explicitesOuiNon (inférés)OuiNon (tout en chaînes)
Chaînes multilignesNon (échappement seulement)Oui (multiples syntaxes)Oui (""")Non
Structures imbriquéesOui (verbeux)Oui (concis)Oui (modéré)Un seul niveau
Risque d'ambiguïté de parsingFaibleÉlevéTrès faibleMoyen
Lisibilité humaineMoyenneÉlevéeÉlevéeÉlevée
Génération machineExcellenteBonneBonneMédiocre
Usages courantsAPIs, manifestesCI/CD, orchestrationConfig projetConfig app legacy

Le Cadre de Décision

Une fois que vous enlevez le langage marketing, le choix se réduit à trois questions.

Est-ce principalement généré par machine ou écrit par des humains ?

Si le fichier est généré par du code et consommé par du code — une réponse d'API, un artefact de build, une entrée de cache sérialisée — utilisez JSON. C'est le plus portable, le plus parseable, et le support des outils est universel. Vous n'avez pas besoin de commentaires dans un fichier qu'aucun humain ne lit. Compresser ces fichiers JSON avant de les transférer sur un réseau peut réduire significativement la taille du payload.

Si un humain écrit et édite ce fichier régulièrement — une config de projet, une description d'environnement, un manifeste d'outil — les commentaires sont non-négociables. Ça élimine le JSON simple.

Contrôlez-vous la chaîne d'outils ?

Si vous êtes bloqué dans un écosystème qui impose un format — Kubernetes exige YAML, GitHub Actions exige YAML, Cargo exige TOML, package.json est JSON — il n'y a pas de décision à prendre. Utilisez ce que l'écosystème attend.

Si vous concevez un nouvel outil ou un nouveau fichier de configuration de zéro, vous avez un vrai choix.

Quelle est la profondeur de l'imbrication, et votre équipe est-elle tolérante aux bugs subtils ?

YAML est expressif mais fragile. Une équipe qui écrit du YAML soigneux, met des guillemets à toutes les chaînes, exécute un linter et comprend la distinction 1.1 versus 1.2 peut l'utiliser en toute sécurité. Une équipe qui avance vite, a des configurations d'éditeurs diverses et ne lance pas de linting YAML dans la CI finira tôt ou tard par rencontrer un Problème de Norvège ou un bug octal en production.

TOML est le choix plus sûr pour la configuration écrite par des humains quand vous contrôlez le format. Les types explicites signifient que l'erreur du parser apparaît au moment du parsing, pas au runtime quand la Norvège est devenue false et que votre logique de feature flag se comporte silencieusement mal.

Référence rapide

  • Réponse d'API ou échange de données entre services : JSON
  • Manifeste de package (principalement écrit par les machines) : JSON
  • Kubernetes, Docker Compose, GitHub Actions, Ansible : YAML (pas un choix)
  • Nouveau fichier de config de projet que vous concevez : TOML
  • Projet Rust : TOML (Cargo.toml)
  • Projet Python : TOML (pyproject.toml)
  • Config d'application legacy avec des besoins simples de clé-valeur : INI (ou migrer vers TOML)

Valider vos Fichiers de Configuration

Les erreurs de syntaxe dans les fichiers de configuration sont parmi les bugs les plus frustrants à diagnostiquer — l'application ne démarre pas, le message d'erreur est cryptique, et l'erreur est un seul caractère mal placé.

Pour JSON, vous pouvez valider et formater du JSON en ligne pour attraper les erreurs immédiatement. Coller un fichier de config JSON dans un validateur avant de le commiter prend cinq secondes et prévient une classe d'échecs CI. Pour des workflows JSON plus approfondis — minifier pour la production, différer les changements de config entre environnements — consultez notre guide sur comment valider, minifier et formater du JSON.

Pour YAML, yamllint est le linter CLI standard. L'exécuter dans la CI n'est pas optionnel si votre équipe écrit du YAML de production. Pour TOML, la plupart des écosystèmes de langage incluent un validateur intégré (cargo check valide Cargo.toml implicitement ; python -c "import tomllib; tomllib.load(open('pyproject.toml', 'rb'))" valide n'importe quel fichier TOML directement).


Le Format est un Contrat

Quel que soit le format choisi, il devient un contrat avec chaque développeur et outil qui touche votre projet. Le changer plus tard est douloureux — pas impossible, mais douloureux. La migration de setup.cfg et setup.py vers pyproject.toml dans l'écosystème Python a pris des années et n'est toujours pas complète.

Choisissez délibérément. JSON quand les machines sont le consommateur principal et la portabilité est critique. YAML quand l'écosystème l'exige ou quand des structures profondément imbriquées doivent être lisibles. TOML quand des humains écrivent le fichier, quand la correction compte, et quand vous voulez que le parser attrape l'ambiguïté au moment de la lecture plutôt qu'elle apparaisse comme un bug runtime six mois plus tard.

Le format de configuration n'est pas juste un format de fichier. C'est une déclaration sur qui édite le fichier, quels outils le traitent, et combien vous faites confiance à la coercition de type implicite. Faites cette déclaration délibérément.


Besoin de valider un fichier de config JSON maintenant ? Essayez le FileCrank JSON Viewer — collez votre JSON, attrapez les erreurs instantanément, et formatez-le pour la lisibilité.