JSON vs YAML vs TOML : la même config, trois écritures
Tout projet finit par avoir un fichier de configuration, et toute équipe finit par débattre de son format. Ce débat mérite d'avoir lieu une fois, sérieusement — parce que les trois candidats font des compromis réellement différents, et que le mauvais choix se paie en lisibilité, en outillage, ou en débogage à 3 h du matin à cause d'une erreur d'indentation invisible.
Voici la même configuration dans les trois formats.
JSON :
{
"name": "my-service",
"port": 8080,
"debug": false,
"database": {
"host": "db.internal",
"replicas": ["eu-1", "eu-2"]
}
}
YAML :
name: my-service
port: 8080
debug: false
database:
host: db.internal
replicas:
- eu-1
- eu-2
TOML :
name = "my-service"
port = 8080
debug = false
[database]
host = "db.internal"
replicas = ["eu-1", "eu-2"]
Mêmes données, trois philosophies. Voyons où chacun gagne — et où chacun mord.
JSON : le format d'échange universel
JSON est le moins ambigu des trois. Les chaînes sont toujours entre guillemets, la structure est toujours explicite, et chaque langage embarque un parseur dans sa bibliothèque standard. C'est le format natif des API web, et la rigueur qui le rend verbeux le rend aussi presque impossible à mal lire.
Forces :
- Universel. Si un outil lit de la config, il lit du JSON.
- Grammaire stricte. Une seule façon canonique d'écrire chaque chose — aucune ambiguïté « c'est une chaîne ou un booléen ? ».
- Adapté aux machines. Trivial à générer, parser, diff-er et valider avec JSON Schema.
Faiblesses :
- Pas de commentaires. Ce point seul le disqualifie pour de la config maintenue à la main. Les contournements type clés
"_comment"sont des hacks (JSONC et JSON5 corrigent ça, mais le support reste inégal). - La taxe ponctuation. Guillemets sur chaque clé, virgules partout — et une virgule finale est une erreur de syntaxe, l'erreur JSON la plus répandue au monde.
- Pas de dates natives, pas de chaînes multi-lignes sans échappements
\n.
Quand un JSON édité à la main casse, le message d'erreur aide rarement. Le passer dans un JSON Formatter localise le caractère exact où le parsing échoue — en général une virgule finale ou une clé sans guillemets.
YAML : lisible, puissant, et truffé de pièges
YAML, c'est ce qu'on obtient quand on optimise uniquement pour la lecture humaine. Pas d'accolades, guillemets facultatifs, commentaires avec #, structure exprimée par l'indentation. C'est la langue commune de l'ops : Kubernetes, Docker Compose, GitHub Actions, Ansible.
Forces :
- Le plus lisible pour des données profondément imbriquées.
- Commentaires, ancres/alias pour la réutilisation, chaînes multi-lignes avec
|et>. - Sur-ensemble de JSON — tout JSON valide est du YAML valide.
Faiblesses — et elles sont célèbres :
- Le problème norvégien. En YAML 1.1 (que beaucoup de parseurs implémentent encore),
nosans guillemets est interprété comme le booléenfalse. Une liste de pays devient donc :
countries: [GB, FR, NO] # NO → false. Désolé, la Norvège.
Le même piège frappe yes, on, off et y.
- Le problème des numéros de version.
version: 1.20est parsé comme le flottant1.2, qui avale ton zéro en silence. Ce que tu voulais, c'étaitversion: "1.20". - L'espace est de la structure. Un seul espace d'indentation en trop change le sens du document sans la moindre erreur de syntaxe. Les tabulations sont interdites, mais ton éditeur peut en insérer quand même.
- La spec est énorme. Neuf façons d'écrire une chaîne multi-ligne ; des règles de typage implicite qui varient d'un parseur à l'autre.
La règle pratique en YAML : mets entre guillemets tout ce qui n'est pas de façon évidente une chaîne, un nombre voulu comme nombre, ou un vrai booléen. Dans le doute, guillemets.
TOML : explicite par conception
TOML (« Tom's Obvious, Minimal Language ») a été conçu en réaction aux deux autres : garder les commentaires et la lisibilité de YAML, garder la non-ambiguïté de JSON. Les chaînes sont toujours entre guillemets, les booléens se limitent à true/false, et il a des dates natives. C'est le format du Cargo.toml de Rust et du pyproject.toml de Python.
[package]
name = "my-app"
version = "1.20" # une chaîne ? alors guillemets : "1.20". Nu, 1.20 est un flottant.
release = 2026-07-10 # type date natif, aucun guillemet nécessaire
[dependencies]
serde = { version = "1.0", features = ["derive"] }
Forces : commentaires, aucune sémantique d'indentation, aucune coercition de type surprise, excellent pour la config plate à moyennement imbriquée.
Faiblesses : l'imbrication profonde devient lourde (les en-têtes [server.http.limits.upload] répètent tout le chemin), les tableaux de tables ([[products]]) déroutent les débutants, et l'adoption hors des écosystèmes Rust/Python reste plus mince. Un TOML Editor avec validation en direct aide dès que tu dépasses deux niveaux d'imbrication.
Comparaison face à face
| Critère | JSON | YAML | TOML |
|---|---|---|---|
| Commentaires | ✗ | ✓ | ✓ |
| Risque d'ambiguïté | Aucun | Élevé (typage implicite) | Faible |
| Sensible aux espaces | Non | Oui | Non |
| Dates natives | ✗ | Partiel | ✓ |
| Imbrication profonde | Correct | Le meilleur | Laborieux |
| Confort d'édition manuelle | Faible | Bon | Bon |
| Disponibilité des parseurs | Totale | Élevée | En croissance |
| Habitat naturel | API, lockfiles | CI/CD, Kubernetes | Cargo, pyproject |
Alors, lequel choisir ?
- Données machine-à-machine (API, caches, lockfiles) : JSON. Sans débat — personne ne l'édite à la main, donc ses faiblesses ne comptent pas.
- Config d'appli ou de projet maintenue à la main : TOML. Commentaires plus zéro ambiguïté, c'est exactement le compromis qu'il faut pour des fichiers que des humains éditent et que des machines croient sur parole.
- L'écosystème a déjà choisi : YAML. Tu ne choisis pas le format de Kubernetes ni de GitHub Actions. Apprends les règles de guillemets et lint sans pitié.
- Un mot sur XML : tu le croiseras encore dans Maven, les manifestes Android et le monde SOAP en entreprise. Il n'est pas « faux », juste verbeux et daté — si tu en hérites un, un XML Formatter le rend navigable.
Un dernier conseil pour les projets TypeScript : quel que soit le format de ta config, génère des types depuis un échantillon avec JSON to TypeScript pour que ton code arrête de deviner ce qu'il y a dedans.
Convertir entre les formats
Comme JSON, YAML et (pour l'essentiel) TOML représentent le même modèle de données — maps, tableaux, scalaires — la conversion est en général sans perte dans le sens JSON→YAML et presque sans perte dans l'autre sens (les commentaires meurent en route, et les ancres YAML sont expansées). Un convertisseur est donc le moyen le plus rapide de migrer une config, ou de vérifier ce qu'un parseur YAML voit vraiment : convertis en JSON, et tout le typage implicite devient explicite. Si NO ressort en false, tu as trouvé ton bug avant la prod.
Convertis ta config maintenant
Colle n'importe quelle config dans le convertisseur JSON ⇄ YAML pour passer d'un format à l'autre instantanément et révéler les surprises de typage cachées. Aucun compte requis.