Anúncios incomodam? Ir Sem anúncios Hoje

YAML versus JSON versus TOML — Qual formato de configuração você realmente deve usar?

Atualizado em

YAML, JSON e TOML armazenam configurações. Eles não são intercambiáveis. O YAML transformará silenciosamente seu código de país em um valor booleano. O JSON não permite que você deixe um comentário. O TOML é o formato que ninguém na sua equipe usou antes. Aqui está como escolher o certo.

YAML vs JSON vs TOML — Qual Formato de Configuração Você Deveria Usar de Fato? 1
ANUNCIADO Remover?

Em 2015, um playbook do Ansible quebrou devido a esta linha:

country: NO

A configuração foi carregada sem erros. Não houve reclamações do parser. Mas country não foi definida como a string "NO". Foi definida como false. Como no YAML 1.1, NO é um booleano. Assim como yes, on, off, ye, e n. Este é o Problema da Noruega, e já está corrompendo silenciosamente configurações há anos.

Isso não é um relato de erro do YAML. É uma estrutura para a decisão que você está prestes a tomar: YAML, JSON ou TOML para seu próximo arquivo de configuração? Cada um tem verdadeiras diferenças, e a resposta "use apenas o que o ecossistema usa" não se aplica sempre.

A Mesma Configuração, Três Formas

Antes do colapso, aqui está a mesma configuração do aplicativo escrita em todas as três formas:

YAML

# App configuration
app:
  name: my-api
  port: 8080
  debug: false

database:
  host: localhost
  port: 5432
  name: mydb
  pool_size: 10

logging:
  level: info
  format: json
  outputs:
    - stdout
    - /var/log/app.log

JSON

{
  "app": {
    "name": "my-api",
    "port": 8080,
    "debug": false
  },
  "database": {
    "host": "localhost",
    "port": 5432,
    "name": "mydb",
    "pool_size": 10
  },
  "logging": {
    "level": "info",
    "format": "json",
    "outputs": [
      "stdout",
      "/var/log/app.log"
    ]
  }
}

TOML

# App configuration
[app]
name = "my-api"
port = 8080
debug = false

[database]
host = "localhost"
port = 5432
name = "mydb"
pool_size = 10

[logging]
level = "info"
format = "json"
outputs = ["stdout", "/var/log/app.log"]

O YAML é o mais compacto, mas também o mais carregado sintaticamente. O JSON é o mais verboso, mas o mais explícito. O TOML está no meio: legível sem as conversões implícitas do YAML.

YAML: Potente, Permissivo e Cheio de Armadilhas

O YAML é a escolha padrão para pipelines CI/CD (GitHub Actions, GitLab CI, CircleCI), manifestos do Kubernetes, playbooks do Ansible e a maioria das ferramentas de desenvolvimento. Você realmente escolhe o YAML — ele escolhe você.

As armadilhas, documentadas:

1. O Problema do Booleano (O Problema da Noruega)

O YAML 1.1 — a especificação que a maioria dos parsers realmente implementa — trata um número alarmante de strings como booleanos:

# YAML 1.1 boolean values (all parsed as true or false)
enabled: yes      # true
disabled: no      # false  
active: on        # true
paused: off       # false
valid: true       # true
invalid: false    # false

# The Norway Problem in practice:
country_codes:
  NO: Norway      # Key "NO" is fine, but value "NO" becomes false
  SE: Sweden
  YES: Yemen      # "YES" also becomes true

# The fix: quote your strings
country_codes:
  NO: "Norway"
  SE: "Sweden"

O YAML 1.2 (lançado em 2009) resolveu isso — apenas true e false são booleanos. O problema é que o PyYAML não adotou completamente o comportamento da versão 1.2 até a versão 6.0 em 2021, e o Go, com seu popular gopkg.in/yaml.v2 ainda usa as semânticas da versão 1.1 até 2024. Se você está usando o Psych do Ruby com versão inferior a 4.0 ou qualquer versão anterior ao 6.0 do PyYAML, você está na versão 1.1.

2. Tabs Vão Matar Sua Configuração

O YAML proíbe o uso de caracteres de tabulação para indentação. Apenas espaços são válidos. Seu editor pode exibir tabs e espaços de forma idêntica, o arquivo pode parecer correto, mas o YAML ainda lançará:

yaml.scanner.ScannerError: while scanning a block mapping
  found character '\t' that cannot start any token

Este é o erro que faz desenvolvedores iniciantes questionarem suas escolhas profissionais. Configure seu editor para expandir tabs em espaços nos arquivos YAML. Todos os editores suportam isso; nem todos os editores têm essa opção ativa por padrão.

3. Strings Multilinhas Não São Obvias

# | (literal block): preserves newlines exactly
description: |
  Line one.
  Line two.
  Line three.
# Result: "Line one.\nLine two.\nLine three.\n"

# > (folded block): folds newlines into spaces
short_desc: >
  This will all become
  one long line.
# Result: "This will all become one long line.\n"

# Trailing newlines: | adds one, |+ adds all, |- strips them all
desc_stripped: |-
  No trailing newline.

Ninguém memoriza isso sem consultar. A mnemônica que uso: | parece um quebra-linha, > parece algo sendo comprimido. Ainda é confuso três anos depois.

Quando o YAML Vence

  • Você está escrevendo manifestos do Kubernetes, fluxos de trabalho do GitHub Actions ou playbooks do Ansible — você não tem escolha.
  • Sua configuração tem muitos comentários explicando valores não óbvios. O YAML suporta comentários inline; o JSON e o TOML também o suportam, mas o YAML se sente mais natural para configurações com muitos anotações.
  • Seus dados têm estruturas profundamente aninhadas que ficariam horríveis com as tabelas planas do TOML.
  • A equipe já está fluente e tem um linter (yamllint) no pipeline.

JSON: O Trabalhador Básico e Reliável

O JSON foi projetado como um formato de intercâmbio de dados, não como um formato de configuração. Douglas Crockford deliberadamente deixou de incluir comentários — seu argumento era que os comentários seriam usados para diretivas que os parsers poderiam diferir. Por isso, package.json não tem comentários e tsconfig.json é tecnicamente JSON com comentários (JSONC), que é uma coisa separada que a maioria dos parsers de JSON não suporta.

Os problemas reais do JSON para arquivos de configuração:

  • Nenhum comentário. Você não pode explicar por que "maxRetries": 3 e não 5. Você não pode deixar um TODO. Você não pode marcar um campo como descontinuado. Isso é realmente doloroso para arquivos de configuração que duram além dos seus autores.
  • Nenhum final de linha com vírgula. Adicionar um item a uma array significa modificar a linha anterior para adicionar uma vírgula. Cada diferença no JSON se torna uma alteração de duas linhas. Cada conflito de fusão é ligeiramente pior do que precisa ser.
  • Verbo para dados aninhados. Seis linhas de chaves e colchetes para o que o YAML faz em três linhas de indentação.
  • Todos os números são do mesmo tipo. O JSON não distingue inteiros de floats. 1 e 1.0 são ambos apenas números, e o que sua linguagem os deserializa depende do parser.

Mas a previsibilidade do JSON também é sua principal característica. Cada linguagem tem um parser de JSON. A especificação é clara. Não há conversões implícitas. Uma string é sempre uma string — "yes" nunca se torna silenciosamente true. Se você precisa validar um arquivo de configuração de forma programática, IO Tools’ JSON Formatter pode detectar erros de sintaxe antes que eles cheguem à produção — útil quando alguém edita um arquivo de configuração manualmente e esquece uma vírgula final.

Quando o JSON Vence

  • Configurações ou respostas de API consumidas por múltiplas linguagens/serviços. O JSON é universal; o suporte ao TOML é fragmentado em alguns ecossistemas.
  • Você precisa de garantias rígidas de tipo. A validação de esquema do JSON é madura, bem suportada e amplamente utilizada (o VS Code usa para autocomplete de configurações).
  • A configuração é gerada por máquina. Ninguém escreve JSON manualmente se puder evitar — mas máquinas geram isso perfeitamente.
  • Você está trabalhando com Node.js ou JavaScript de front-end, onde o JSON é um cidadão nativo.

TOML: Configuração Opinada, Feita Corretamente

O TOML (Tom’s Obvious, Minimal Language) foi criado por Tom Preston-Werner, co-fundador do GitHub, especificamente para arquivos de configuração. Atingiu a versão 1.0 em janeiro de 2021. É o formato padrão para o Rust’s Cargo.toml, o Python’s pyproject.tomle sites estáticos Hugo.

A filosofia de design do TOML: os tipos devem ser explícitos, a estrutura deve ser plana o máximo possível e deve haver exatamente uma maneira óbvia de escrever qualquer valor de configuração.

# Types are unambiguous in TOML
name = "my-app"          # string: always quoted
port = 8080              # integer
threshold = 3.14         # float
enabled = true           # boolean: only true/false, no yes/no
created = 2024-01-15     # date: native type
tags = ["api", "prod"]   # array

# "yes" is just a string. Always.
country = "NO"           # string "NO", no boolean nonsense

As arestas arredondadas:

  • A sintaxe de arrays de tabelas é realmente confusa. [[products]] e [products.details] parecem semelhantes, mas comportam-se completamente de forma diferente. A especificação faz sentido; a distinção visual não.
  • A profundidade da aninhamento se torna verbosa. O que o YAML faz em 5 linhas indentadas, o TOML faz em 3 cabeçalhos separados. Para configurações com mais de 3 níveis de profundidade, o TOML começa a parecer a ferramenta errada.
  • Disponibilidade dos parsers. Existem parsers do TOML para todas as principais linguagens, mas eles variam na conformidade com a especificação. O conjunto de testes de conformidade do TOML revela regularmente casos extremos. Os parsers do JSON foram testados em ordens de magnitude maiores de uso.
  • Familiaridade da equipe. Se você usar o TOML fora do ecossistema do Rust ou do Python, espera que pelo menos um colega abra um PR com “o que é esse formato?”

Quando o TOML Vence

  • Projetos em Rust — Cargo.toml é o padrão e a ferramentaria é excelente.
  • Projetos em Python usando pyproject.toml (PEP 518) — isso é agora a casa recomendada para configurações de ferramentas como Black, Ruff, mypy e pytest.
  • Configurações simples e planas onde a sensibilidade ao indentação do YAML seria um problema.
  • Você quer suporte nativo a datas/horas sem serializar para strings.

O Guia Rápido de Decisão

  • Kubernetes / pipeline CI/CD / playbook do Ansible? YAML. Sem escolha.
  • Configuração de API consumida por serviços em diferentes linguagens? JSON.
  • Projeto em Rust? TOML (convenção Cargo.toml).
  • Configuração de projeto em Python (linters, formatters, ferramentas de build)? TOML (pyproject.toml é o padrão agora).
  • Configuração de site estático (Hugo, Zola)? TOML, embora esses geralmente suportem todos os três.
  • Configuração de projeto em Node.js? JSON (ecossistema package.json), ou YAML se você precisar de comentários.
  • Humanos irão editar isso com frequência e precisam deixar anotações? YAML ou TOML (ambos suportam comentários). Não JSON.
  • Você quer segurança rígida de tipo e validação de esquema? JSON + Esquema do JSON.

A resposta honesta para a maioria dos novos projetos: use o que o ecossistema da linguagem principal espera. O Rust espera TOML. As ferramentas do Python esperam TOML ou YAML. O Node.js espera JSON. Se você estiver escrevendo algo linguagem-agnostic, o TOML para configurações editadas por humanos e o JSON para configurações geradas por máquinas e consumidas por máquinas é uma divisão razoável.

Quer eliminar anúncios? Fique sem anúncios hoje mesmo

Instale nossas extensões

Adicione ferramentas de IO ao seu navegador favorito para acesso instantâneo e pesquisa mais rápida

Ao Extensão do Chrome Ao Extensão de Borda Ao Extensão Firefox Ao Extensão Opera

O placar chegou!

Placar é uma forma divertida de acompanhar seus jogos, todos os dados são armazenados em seu navegador. Mais recursos serão lançados em breve!

ANUNCIADO Remover?
ANUNCIADO Remover?
ANUNCIADO Remover?

Notícias com destaques técnicos

Envolver-se

Ajude-nos a continuar fornecendo ferramentas gratuitas valiosas

Compre-me um café
ANUNCIADO Remover?