JSON, TOML, YAML o CSON: scegliere un formato di configurazione
In sintesi: I file di configurazione hanno bisogno di commenti, date e testo multiriga, ed è qui che JSON è carente. Confronta JSON, TOML, YAML e CSON, e scopri cosa perde sempre la conversione.

In sintesi: usa JSON per lo scambio tra macchine, e scegli TOML o YAML per la configurazione mantenuta dalle persone in base all'ecosistema (YAML per Kubernetes e CI, TOML per strutture piatte o date native); ripiega su JSONC solo quando non sei sicuro che il lettore supporti il dialetto.
JSON esiste per le macchine che scambiano dati; un file di configurazione è scritto da persone per persone. Confondi i due e ottieni un
config.jsonche non può contenere un commento e che nessuno osa sfoltire.
1. Parti da due tipi diversi di file
Scambio di dati e configurazione non condividono lo stesso obiettivo, anche se spesso la stessa persona li scrive entrambi sulla stessa macchina.
| Dimensione | Scambio di dati | Configurazione |
|---|---|---|
| Chi lo scrive | Un programma che serializza un valore | Una persona, o una persona che modifica output generati |
| Chi lo legge | Il programma di qualcun altro | Il tuo programma |
| Cosa conta | Zero ambiguità, dimensione, velocità di parsing | Leggibilità, commenti, diff revisionabili |
| Frequenza di modifica | Ogni richiesta | Occasionalmente, con revisione |
| Costo di un errore | Una risposta 500 | Un servizio che non si avvia |
JSON segna quasi il massimo nella colonna di sinistra: grammatica minimale, un parser in ogni linguaggio, e nessun commento significa nessun problema di "commento allontanatosi dal valore". Nella colonna di destra, la sua rigidità è puro attrito: niente commenti, niente virgole finali, niente date, e il testo multiriga deve essere compresso in una riga con \n.
2. I quattro contendenti e la loro sintassi
- JSON: definito da RFC 8259 ed ECMA-404, con esattamente sei tipi di valore: oggetto, array, stringa, numero, booleano e
null. È lo standard di scambio de facto e l'unico formato che non richiede una decisione di scelta. - TOML: creato da Tom Preston-Werner, con la v1.0.0 pubblicata a gennaio 2021. Il suo obiettivo dichiarato è un formato di configurazione minimale con semantica ovvia che mappa senza ambiguità su una hash table.
Cargo.tomlepyproject.tomllo usano per impostazione predefinita. - YAML: la specifica attuale è la 1.2.2. L'indentazione esprime la gerarchia, e supporta commenti, anchor e documenti multipli. I manifest di Kubernetes, GitHub Actions e Ansible dipendono tutti da lui, al costo di una specifica ampia e di differenze tra implementazioni.
- CSON: CoffeeScript Object Notation, che scrive la configurazione usando i letterali oggetto di CoffeeScript. Il
config.csondi Atom lo usava. Supporta commenti, chiavi senza virgolette e virgole finali, ma il suo ecosistema non è mai uscito dal mondo JavaScript.
2.1 Confronto delle capacità
| Capacità | JSON | TOML | YAML | CSON |
|---|---|---|---|---|
| Commenti | ✗ | ✓ # |
✓ # |
✓ # |
| Virgole finali | ✗ | ✓ (array, tabelle inline) | ✓ (collezioni flow) | ✓ |
| Chiavi senza virgolette | ✗ | ✓ | ✓ | ✓ |
| Date-ora native | ✗ (solo stringa) | ✓ quattro tipi date-ora | ✓ (auto-analizzate nella 1.1) | ✗ |
| Stringhe multiriga | ✗ (escape \n) |
✓ """ e ''' |
✓ scalari block e folded | ✓ heredoc |
| Intervallo degli interi | Illimitato nella specifica, double in pratica | Con segno a 64 bit, senza perdite | Precisione arbitraria più .inf/.nan |
Segue JavaScript |
| Annidamento | Graffe e parentesi | Tabelle, array di tabelle, chiavi a punti | Indentazione | Indentazione |
| Sensibile all'indentazione | ✗ | ✗ | ✓ | ✓ |
null |
✓ | ✗ | ✓ | ✓ |
| Copertura degli strumenti | Ogni linguaggio | Linguaggi mainstream | Ogni linguaggio, implementazioni variabili | Solo JavaScript |
Due celle meritano una nota. TOML non ha null, che è il fallimento più comune quando si converte da JSON. Il comportamento "data nativa" di YAML significa che un parser 1.1 trasforma automaticamente 2026-10-31 in un oggetto data, quindi il tipo cambia tra linguaggi diversi.
3. Commenti: l'unica debolezza di JSON
La conclusione prima: se una persona mantiene il file e deve spiegare perché un valore è quello che è, non usare JSON standard.
Ci sono quattro strade pratiche, ordinate per quanto sono invasive:
- Passa a JSONC, che è JSON standard più commenti e virgole finali.
settings.jsonetsconfig.jsondi VS Code lo usano. Il costo è che il lettore deve usare un parser consapevole dei commenti comejsonc-parser; il sempliceJSON.parsefallisce. I dettagli sono in JSON5 e JSONC: JSON con commenti. - Mantieni un documento sidecar.
config.jsonresta leggibile dalle macchine, mentreconfig.mdspiega cosa significa ogni campo e perché contiene quel valore. Entrambi vivono nella stessa directory e cambiano nello stesso commit. - Metti le spiegazioni nello schema. Le parole chiave
descriptione$commentdi JSON Schema possono documentare i campi, ma gli schemi raramente vengono distribuiti insieme alla configurazione a runtime, quindi chi legge la configurazione potrebbe non vederle mai. - Passa a TOML o YAML, lasciando che il formato stesso fornisca commenti che ogni parser capisce.
{
// Fixed at 8080: the frontend build script reads this port for its proxy
"port": 8080,
// Disable watching to avoid exhausting inodes in CI
"watch": false
}
JSONC è comunque un dialetto: l'estensione resta .json, ma solo alcuni strumenti lo capiscono. Quando i dati escono dal team o attraversano il confine di un servizio, la linea tra JSONC e JSON standard deve essere documentata.
4. Date e stringhe multiriga: il terreno di casa di TOML
TOML promuove le date-ora a tipo di prima classe con quattro varianti: date-ora con offset, date-ora locale, data locale e ora locale. Le stringhe multiriga hanno una sintassi dedicata che preserva gli a capo:
title = "json-toolkit"
created = 2026-10-31T09:00:00+08:00
description = """
A JSON toolkit for developers.
Every operation runs locally in the browser.
"""
La stessa informazione in JSON deve retrocedere la data a stringa e sottoporre a escape gli a capo:
{
"title": "json-toolkit",
"created": "2026-10-31T09:00:00+08:00",
"description": "A JSON toolkit for developers.\nEvery operation runs locally in the browser."
}
In JSON, "created" è solo una stringa che per caso sembra una data, quindi l'informazione di tipo deve vivere in un contratto dei campi: entrambe le parti devono concordare che il campo è sempre RFC 3339. TOML dà al parser un vero oggetto data, senza bisogno di accordi verbali.
Anche YAML può contenere testo multiriga, ma i due stili block significano cose diverse: | preserva gli a capo mentre > li ripiega in spazi. Scegli quello sbagliato e un indirizzo o un'istruzione SQL collassano in una sola riga, un errore molto difficile da intercettare in revisione.
5. Numeri: la differenza più trascurata
La specifica JSON non pone limiti alla precisione numerica, ma RFC 8259 avverte anche che l'interoperabilità è più sicura quando i numeri vengono trattati come double IEEE 754. In JavaScript, gli interi oltre 2^53 - 1 perdono precisione in silenzio:
JSON.parse('{"id":9007199254740993}').id
// 9007199254740992: the last digit is gone
TOML richiede che gli interi con segno a 64 bit siano gestiti senza perdite e che sollevino un errore invece di troncare in silenzio; i float seguono binary64 e possono anche essere inf o nan. YAML 1.1 porta un fardello più vecchio: 1:30 viene interpretato come 90 (sessagesimale), e i booleani accettano yes, no, on e off. Da qui il classico "problema della Norvegia", in cui il codice paese NO diventa false.
Per il denaro, non affidarti mai alla virgola mobile in nessuno di questi formati: usa unità minori intere, stringhe o un tipo decimale del database. Formattazione e precisione sono approfondite in i confini della conversione JSON, YAML e XML.
6. Tabelle e annidamento: i confini rigidi di TOML
TOML esprime l'annidamento con tabelle e array di tabelle:
[server]
port = 8080
[[routes]]
path = "/parse"
method = "POST"
[[routes]]
path = "/minify"
method = "POST"
Ha due confini rigidi che devi conoscere prima di convertire:
- La radice di un documento TOML è una tabella, quindi un documento JSON il cui livello superiore è un array (come
[1, 2, 3]) non ha una rappresentazione TOML legale; deve essere racchiuso come{"items": [...]}; - TOML non ha
null, quindi un campo JSONnulldeve essere eliminato oppure sostituito con una stringa vuota o un valore sentinella, spingendo la semantica sul consumatore.
YAML è l'opposto: la profondità di annidamento è illimitata, e anchor più chiavi di merge possono riutilizzare frammenti:
defaults: &defaults
retries: 3
timeoutMs: 5000
server:
<<: *defaults
port: 8080
Gli anchor sono una capacità solo YAML e una perdita garantita durante la conversione: JSON non ha sintassi di riferimento, quindi il file espanso cresce e nulla registra che le due sezioni erano la stessa configurazione.
7. Scegliere per scenario
| Scenario | Raccomandazione | Motivo |
|---|---|---|
| API pubbliche, code di messaggi, cache | JSON | Massima universalità, costo di negoziazione zero |
| Configurazione applicativa, piatta e tipizzata | TOML | Commenti, date, interi senza perdite, comportamento stabile del parser |
| Kubernetes, CI, Ansible | YAML | L'ecosistema è bloccato; cambiare formato significa cambiare strumenti |
VS Code, tsconfig.json |
JSONC | Supportato nativamente, nessun nuovo formato da introdurre |
| Riutilizzo di frammenti di configurazione | YAML | Anchor e chiavi di merge sono l'unica opzione pronta |
| Generati e solo macchina | JSON (minificato) | Nessun commento necessario, miglior dimensione e costo di parsing |
| Progetti legacy Atom o CoffeeScript | CSON, ma pianifica una migrazione | L'ecosistema è marginale e i costi di migrazione crescono nel tempo |
Una regola pratica: lascia che sia l'ecosistema a scegliere il formato di configurazione, non le preferenze personali. Scrivere Rust significa Cargo.toml, distribuire su Kubernetes significa YAML, e costruire un'estensione di VS Code significa JSONC. Solo in un progetto nuovo senza vincoli di ecosistema "quale è più bello da scrivere" è una vera domanda.
8. Confini della conversione
| Direzione | Informazione che si perde sempre | Consiglio |
|---|---|---|
| JSON → TOML | null, array di livello superiore, chiavi non esprimibili |
Normalizza prima la struttura ed elimina i campi vuoti |
| TOML → JSON | Commenti, tipi data, inf / nan |
Converti le date in stringhe RFC 3339 |
| YAML → JSON | Commenti, anchor e chiavi di merge, tag, documenti multipli | Espandi prima gli anchor, poi converti documento per documento |
| JSON → YAML | Nessuna perdita strutturale, ma le stringhe data possono essere auto-analizzate | Metti tra virgolette le stringhe data |
| CSON → JSON | Commenti, espressioni CoffeeScript | Migra una volta; non sincronizzare in entrambe le direzioni |
Gli strumenti di conversione garantiscono i valori, mai i commenti. Quindi non progettare una pipeline a due vie in cui "JSON è la sorgente e YAML è un artefatto di build". O genera in una sola direzione, o mantieni un unico file sorgente.
9. Checklist
- [ ] Documenta quali tipi di file usano quale formato, ed elenca i dialetti consentiti;
- [ ] Preferisci TOML o YAML per la configurazione mantenuta dalle persone, e JSON per lo scambio tra macchine;
- [ ] Memorizza le date in JSON come stringhe RFC 3339 e segna il formato nello schema;
- [ ] Rappresenta denaro e interi oltre
2^53come stringhe o unità minori, mai come float; - [ ] Valida ogni formato in CI con il proprio parser, mai con
JSON.parseper YAML; - [ ] Migra i formati in una sola direzione, ed elimina il file vecchio così che i due non possano divergere.
FAQ
Perché la conversione da JSON a TOML fallisce su alcuni campi?
TOML non ha null, e la radice di un documento TOML è una tabella, quindi un campo JSON null deve essere eliminato o sostituito con una stringa vuota o sentinella, e un array di livello superiore deve essere racchiuso come {"items": [...]}. Anche commenti, tipi data e inf/nan si perdono nella direzione opposta, ed è per questo che la conversione dovrebbe essere unidirezionale.
Devo mantenere due file di configurazione in formati diversi?
No. Gli strumenti di conversione garantiscono i valori ma mai i commenti, quindi una pipeline in cui "JSON è la sorgente e YAML è un artefatto di build" divergerà. O genera in una sola direzione, o mantieni un unico file sorgente ed elimina quello vecchio dopo la migrazione.
Come aggiungo commenti a un file di configurazione JSON?
Il JSON standard non ha commenti. Puoi passare a JSONC (il dialetto di VS Code, letto con jsonc-parser), mantenere un documento sidecar che spieghi ogni campo, oppure passare a TOML o YAML. I file inviati ad altri sistemi dovrebbero restare JSON standard, con le spiegazioni nella documentazione o in uno schema.
TOML o YAML sono migliori per la configurazione applicativa?
Scegli TOML quando la struttura è piatta, in gran parte coppie chiave-valore, e le date native contano; la sua semantica è più prevedibile e le differenze tra parser sono minori. Scegli YAML quando ti serve un annidamento profondo, documenti multipli, riutilizzo con anchor, o quando l'ecosistema di destinazione è YAML-first, come Kubernetes o CI. Entrambi supportano i commenti, quindi il vero fattore distintivo è la complessità strutturale e il blocco dell'ecosistema.
Perché NO diventa false in YAML?
YAML 1.1 tratta yes, no, on, off, y e n come booleani, quindi il codice paese della Norvegia NO viene interpretato come false. È il "problema della Norvegia". Evitalo usando un'implementazione che segue YAML 1.2, oppure mettendo tra virgolette ogni stringa che potrebbe essere fraintesa.
CSON vale ancora la pena?
Non per i progetti nuovi. CSON dipende dall'ecosistema CoffeeScript, ha pochi strumenti mantenuti e un supporto limitato per editor e CI; dopo che Atom ha smesso di essere mantenuto, i suoi casi d'uso si sono ridotti ulteriormente. Se un progetto ha già configurazioni CSON, pianifica una migrazione una tantum a JSON, TOML o YAML invece di aggiungerne altro.