JSON, TOML, YAML ou CSON: escolhendo um formato de configuração
Resumo: Arquivos de configuração precisam de comentários, datas e texto multilinha, que é onde o JSON fica devendo. Compare JSON, TOML, YAML e CSON e veja o que a conversão sempre perde.

Resumo da ópera: use JSON para troca entre máquinas e escolha TOML ou YAML para configuração mantida por humanos conforme o ecossistema (YAML para Kubernetes e CI, TOML para estruturas planas ou datas nativas); recorra ao JSONC apenas quando não tiver certeza de que o leitor suporta o dialeto.
O JSON existe para máquinas trocando dados; um arquivo de configuração é escrito por pessoas para pessoas. Misture os dois e você terá um
config.jsonque não consegue guardar comentário e que ninguém ousa enxugar.
1. Comece pelos dois tipos diferentes de arquivo
Troca de dados e configuração não compartilham o mesmo objetivo, embora a mesma pessoa frequentemente escreva os dois na mesma máquina.
| Dimensão | Troca de dados | Configuração |
|---|---|---|
| Quem escreve | Um programa serializando um valor | Um humano, ou um humano editando saída gerada |
| Quem lê | O programa de outra pessoa | Seu próprio programa |
| O que importa | Zero ambiguidade, tamanho, velocidade de análise | Legibilidade, comentários, diffs revisáveis |
| Frequência de mudança | A cada requisição | Ocasionalmente, com revisão |
| Custo de um erro | Uma resposta 500 | Um serviço que não inicia |
O JSON pontua quase perfeitamente na coluna da esquerda: gramática mínima, um analisador em toda linguagem e ausência de comentários significa ausência do problema de "o comentário se afastou do valor". Na coluna da direita, seu rigor é puro atrito: sem comentários, sem vírgulas finais, sem datas, e texto multilinha precisa ser comprimido em uma linha com \n.
2. Os quatro candidatos e sua sintaxe
- JSON: definido pela RFC 8259 e pela ECMA-404, com exatamente seis tipos de valor: objeto, array, string, número, booleano e
null. É o padrão de fato de troca e o único formato que não exige decisão de seleção. - TOML: criado por Tom Preston-Werner, com a v1.0.0 publicada em janeiro de 2021. Seu objetivo declarado é um formato de configuração mínimo, com semântica óbvia que mapeia sem ambiguidade para uma tabela hash.
Cargo.tomlepyproject.tomlo usam por padrão. - YAML: a especificação atual é a 1.2.2. A indentação expressa a hierarquia, e ele suporta comentários, âncoras e múltiplos documentos. Manifests do Kubernetes, GitHub Actions e Ansible todos dependem dele, ao custo de uma especificação grande e diferenças entre implementações.
- CSON: CoffeeScript Object Notation, que escreve configuração usando literais de objeto CoffeeScript. O
config.csondo Atom o usava. Suporta comentários, chaves sem aspas e vírgulas finais, mas seu ecossistema nunca saiu do mundo JavaScript.
2.1 Comparação de capacidades
| Capacidade | JSON | TOML | YAML | CSON |
|---|---|---|---|---|
| Comentários | ✗ | ✓ # |
✓ # |
✓ # |
| Vírgulas finais | ✗ | ✓ (arrays, tabelas inline) | ✓ (coleções flow) | ✓ |
| Chaves sem aspas | ✗ | ✓ | ✓ | ✓ |
| Data-hora nativa | ✗ (apenas string) | ✓ quatro tipos de data-hora | ✓ (auto-analisada em 1.1) | ✗ |
| Strings multilinha | ✗ (escapes \n) |
✓ """ e ''' |
✓ escalares em bloco e dobrados | ✓ heredoc |
| Faixa de inteiros | Ilimitada na especificação, double na prática | 64 bits com sinal, precisa ser sem perdas | Precisão arbitrária mais .inf/.nan |
Segue o JavaScript |
| Aninhamento | Chaves e colchetes | Tabelas, arrays de tabelas, chaves pontuadas | Indentação | Indentação |
| Sensível à indentação | ✗ | ✗ | ✓ | ✓ |
null |
✓ | ✗ | ✓ | ✓ |
| Cobertura de ferramentas | Toda linguagem | Linguagens mainstream | Toda linguagem, implementações variadas | Apenas JavaScript |
Duas células merecem nota. O TOML não tem null, que é a falha mais comum ao converter de JSON. O comportamento de "data nativa" do YAML significa que um analisador 1.1 transforma 2026-10-31 em um objeto de data automaticamente, então o tipo muda entre linguagens.
3. Comentários: a única fraqueza do JSON
A conclusão primeiro: se um humano mantém o arquivo e precisa explicar por que um valor é o que é, não use JSON padrão.
Há quatro rotas práticas, ordenadas pelo quanto invadem:
- Mude para JSONC, que é JSON padrão mais comentários e vírgulas finais.
settings.jsonetsconfig.jsondo VS Code o usam. O custo é que o leitor precisa de um analisador que entenda comentários, comojsonc-parser;JSON.parsepuro falha. Detalhes em JSON5 e JSONC: JSON com comentários. - Mantenha um documento auxiliar.
config.jsoncontinua legível por máquina, enquantoconfig.mdexplica o que cada campo significa e por que guarda aquele valor. Ambos vivem no mesmo diretório e mudam no mesmo commit. - Coloque explicações no schema. As palavras-chave
descriptione$commentdo JSON Schema documentam campos, mas schemas raramente acompanham a configuração em tempo de execução, então a pessoa que lê a configuração pode nunca vê-las. - Mude para TOML ou YAML, deixando o próprio formato fornecer comentários que todo analisador entende.
{
// Fixado em 8080: o script de build do frontend lê esta porta para o proxy
"port": 8080,
// Desative o watch para evitar esgotar inodes no CI
"watch": false
}
JSONC ainda é um dialeto: a extensão continua .json, mas só algumas ferramentas o entendem. Quando os dados saem da equipe ou cruzam uma fronteira de serviço, a linha entre JSONC e JSON padrão precisa estar documentada.
4. Datas e strings multilinha: o terreno do TOML
O TOML promove data-hora a um tipo de primeira classe com quatro variantes: data-hora com offset, data-hora local, data local e hora local. Strings multilinha têm sintaxe dedicada que preserva quebras de linha:
title = "json-toolkit"
created = 2026-10-31T09:00:00+08:00
description = """
A JSON toolkit for developers.
Every operation runs locally in the browser.
"""
A mesma informação em JSON precisa rebaixar a data para string e escapar as quebras de linha:
{
"title": "json-toolkit",
"created": "2026-10-31T09:00:00+08:00",
"description": "A JSON toolkit for developers.\nEvery operation runs locally in the browser."
}
Em JSON, "created" é apenas uma string que por acaso parece uma data, então a informação de tipo precisa viver em um contrato de campo: os dois lados precisam concordar que o campo é sempre RFC 3339. O TOML dá ao analisador um objeto de data real, sem acordo verbal necessário.
O YAML também consegue guardar texto multilinha, mas os dois estilos de bloco significam coisas diferentes: | preserva quebras de linha enquanto > as dobra em espaços. Escolha o errado e um endereço ou um comando SQL colapsa em uma linha, um erro muito difícil de pegar na revisão.
5. Números: a diferença mais negligenciada
A especificação JSON não limita a precisão numérica, mas a RFC 8259 também avisa que a interoperabilidade é mais segura quando os números são tratados como doubles IEEE 754. Em JavaScript, inteiros acima de 2^53 - 1 perdem precisão silenciosamente:
JSON.parse('{"id":9007199254740993}').id
// 9007199254740992: o último dígito sumiu
O TOML exige que inteiros de 64 bits com sinal sejam tratados sem perdas e que gerem erro em vez de truncar silenciosamente; floats seguem binary64 e também podem ser inf ou nan. O YAML 1.1 carrega um ônus antigo: 1:30 é analisado como 90 (sexagesimal), e booleanos aceitam yes, no, on e off. Daí o clássico "problema da Noruega", em que o código de país NO vira false.
Para dinheiro, nunca confie em ponto flutuante em nenhum desses formatos: use unidades menores inteiras, strings ou um tipo decimal de banco de dados. Formatação e precisão são aprofundadas em as fronteiras da conversão entre JSON, YAML e XML.
6. Tabelas e aninhamento: as fronteiras rígidas do TOML
O TOML expressa aninhamento com tabelas e arrays de tabelas:
[server]
port = 8080
[[routes]]
path = "/parse"
method = "POST"
[[routes]]
path = "/minify"
method = "POST"
Ele tem duas fronteiras rígidas que você precisa conhecer antes de converter:
- A raiz de um documento TOML é uma tabela, então um documento JSON cujo nível superior é um array (como
[1, 2, 3]) não tem representação TOML legal; ele precisa ser envolvido como{"items": [...]}; - O TOML não tem
null, então um campo JSONnullprecisa ser descartado ou substituído por uma string vazia ou um valor sentinela, com a semântica empurrada para o consumidor.
O YAML é o oposto: a profundidade de aninhamento é ilimitada, e âncoras mais merge keys conseguem reutilizar fragmentos:
defaults: &defaults
retries: 3
timeoutMs: 5000
server:
<<: *defaults
port: 8080
Âncoras são uma capacidade exclusiva do YAML e uma perda garantida durante a conversão: o JSON não tem sintaxe de referência, então o arquivo expandido cresce e nada registra que as duas seções costumavam ser a mesma configuração.
7. Escolha por cenário
| Cenário | Recomendação | Motivo |
|---|---|---|
| APIs públicas, filas de mensagens, caches | JSON | Máxima universalidade, custo de negociação zero |
| Configuração de aplicação, plana e tipada | TOML | Comentários, datas, inteiros sem perdas, comportamento de analisador estável |
| Kubernetes, CI, Ansible | YAML | O ecossistema está preso a ele; mudar o formato significa mudar as ferramentas |
VS Code, tsconfig.json |
JSONC | Suportado nativamente, nenhum formato novo a introduzir |
| Reutilização de fragmentos de configuração | YAML | Âncoras e merge keys são a única opção pronta |
| Gerado e somente máquina | JSON (minificado) | Sem necessidade de comentários, melhor tamanho e custo de análise |
| Projetos legados Atom ou CoffeeScript | CSON, mas planeje uma migração | O ecossistema é marginal e o custo de migração cresce com o tempo |
Uma regra geral: deixe o ecossistema escolher o formato de configuração, não a preferência pessoal. Escrever Rust significa Cargo.toml, implantar no Kubernetes significa YAML, e construir uma extensão do VS Code significa JSONC. Só em um projeto novo, sem restrições de ecossistema, "qual é mais gostoso de escrever" é uma pergunta real.
8. Fronteiras de conversão
| Direção | Informação sempre perdida | Conselho |
|---|---|---|
| JSON → TOML | null, arrays de nível superior, chaves que não podem ser expressas |
Normalize a estrutura e descarte campos vazios primeiro |
| TOML → JSON | Comentários, tipos de data, inf / nan |
Converta datas em strings RFC 3339 |
| YAML → JSON | Comentários, âncoras e merge keys, tags, múltiplos documentos | Expanda as âncoras primeiro e depois converta documento por documento |
| JSON → YAML | Nenhuma perda estrutural, mas strings de data podem ser auto-analisadas | Coloque strings de data entre aspas |
| CSON → JSON | Comentários, expressões CoffeeScript | Migre uma vez; não sincronize nas duas direções |
Ferramentas de conversão garantem os valores, nunca os comentários. Então não projete um pipeline bidirecional onde "JSON é a fonte e YAML é um artefato de build". Ou gere apenas em uma direção, ou mantenha um único arquivo de origem.
9. Lista de verificação
- [ ] Documente quais tipos de arquivo usam qual formato e liste os dialetos permitidos;
- [ ] Prefira TOML ou YAML para configuração mantida por humanos e JSON para troca entre máquinas;
- [ ] Armazene datas em JSON como strings RFC 3339 e marque o formato no schema;
- [ ] Represente dinheiro e inteiros acima de
2^53como strings ou unidades menores, nunca como floats; - [ ] Valide cada formato no CI com o seu próprio analisador, nunca com
JSON.parsepara YAML; - [ ] Migre formatos apenas em uma direção e exclua o arquivo antigo para que os dois não divergam.
Perguntas frequentes
Por que converter JSON para TOML falha em alguns campos?
O TOML não tem null, e a raiz de um documento TOML é uma tabela, então um campo JSON null precisa ser descartado ou substituído por uma string vazia ou sentinela, e um array de nível superior precisa ser envolvido como {"items": [...]}. Comentários, tipos de data e inf/nan também se perdem ao mover na direção oposta, o que é por que a conversão deve ser unidirecional.
Devo manter dois arquivos de configuração em formatos diferentes?
Não. Ferramentas de conversão garantem os valores mas nunca os comentários, então um pipeline onde "JSON é a fonte e YAML é um artefato de build" vai divergir. Ou gere apenas em uma direção, ou mantenha um único arquivo de origem e exclua o antigo após migrar.
Como adiciono comentários a um arquivo de configuração JSON?
O JSON padrão não tem comentários. Você pode mudar para JSONC (o dialeto do VS Code, lido com jsonc-parser), manter um documento auxiliar que explica cada campo, ou mudar para TOML ou YAML. Arquivos enviados a outros sistemas devem permanecer em JSON padrão, com explicações vivendo na documentação ou em um schema.
TOML ou YAML é melhor para configuração de aplicação?
Escolha TOML quando a estrutura é plana, majoritariamente pares chave-valor, e datas nativas importam; sua semântica é mais previsível e as diferenças entre analisadores são menores. Escolha YAML quando precisar de aninhamento profundo, múltiplos documentos, reutilização por âncoras, ou quando o ecossistema alvo é YAML-first, como Kubernetes ou CI. Ambos suportam comentários, então o verdadeiro diferenciador é a complexidade estrutural e o aprisionamento ao ecossistema.
Por que NO vira false no YAML?
O YAML 1.1 trata yes, no, on, off, y e n como booleanos, então o código de país da Noruega NO é analisado como false. Este é o "problema da Noruega". Evite-o usando uma implementação que siga o YAML 1.2, ou colocando entre aspas toda string que possa ser mal interpretada.
CSON ainda vale a pena?
Não para projetos novos. O CSON depende do ecossistema CoffeeScript, tem poucas ferramentas mantidas e suporte limitado em editores e CI; depois que o Atom deixou de ser mantido, seus casos de uso encolheram ainda mais. Se um projeto já tem configuração CSON, agende uma migração única para JSON, TOML ou YAML em vez de acrescentar mais.