Pular para o conteúdo principal

developer-tools

YAML vs JSON vs TOML: Quando Usar Qual Formato de Configuração

robinhood-projects13 min de leitura

Visualizador, Formatador e Editor de JSON

Visualize, edite e formate JSON numa árvore interativa em tempo real. Edição inline de valores, renomeação de chaves, adicionar/remover nós, suporte a comentários JSONC e exportação com um clique — tudo no seu navegador.

Usar ferramenta →

Visualizador CSV & Tabela Inteligente

Abra qualquer CSV como tabela interativa: ordene colunas, filtre linhas, edite células e exporte para CSV, XLS ou XLSX. Totalmente no navegador, sem cadastro.

Usar ferramenta →

YAML vs JSON vs TOML: Quando Usar Qual Formato de Configuração

Todo projeto eventualmente tem um problema de configuração. Você precisa armazenar credenciais de banco de dados, definir ambientes de implantação, descrever um pipeline de CI ou conectar dependências — e alguém tem que escolher um formato. JSON? YAML? TOML? A escolha parece arbitrária até que te morde.

Arquivos Docker Compose são YAML. package.json é JSON. O manifesto de dependências do Rust (Cargo.toml) é TOML. O empacotamento Python (pyproject.toml) é TOML. Workflows do GitHub Actions são YAML. Isso não é aleatório — cada formato venceu a batalha de adoção em seu domínio por razões específicas. Entender essas razões permite fazer uma escolha deliberada em vez de optar pelo "o que o template usava."

Este artigo é um guia de decisão. Ao final, você conhecerá os verdadeiros trade-offs de cada formato, verá os footguns exatos do YAML que causaram incidentes em produção, e terá um framework claro para escolher.


O Ancestral Comum: Arquivos INI

Antes de mergulhar nos contendores modernos, vale a pena passar trinta segundos nos arquivos INI — o formato ao qual os três estão, de certa forma, reagindo.

Arquivos INI se parecem com isso:

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

Simples, legível por humanos, suporta seções, suporta comentários. Os problemas são igualmente simples: sem especificação padrão (cada parser interpreta os casos extremos de forma diferente), sem estruturas aninhadas além de um nível, sem arrays, sem tipos explícitos. Tudo é uma string a menos que sua aplicação decida o contrário.

INI estava bem para php.ini em 1997. Não está bem para descrever um deployment do Kubernetes em 2026. Mas identificou os objetivos certos — editabilidade humana e comentários — que os formatos modernos ou herdaram ou descartaram.


JSON: A Língua Franca dos Dados

JSON (JavaScript Object Notation) foi padronizado no início dos anos 2000 e se tornou o formato wire dominante para APIs. Sua força vem de suas restrições.

O que JSON faz certo

JSON tem exatamente seis tipos de valor: string, número, booleano, null, array e objeto. A especificação é inequívoca. Todo parser JSON compatível analisará o mesmo documento de forma idêntica. Sem surpresas.

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

O tipo de port é inequivocamente um número. ssl é inequivocamente um booleano. allowed_origins é inequivocamente um array de strings. Um parser JSON não pode interpretar mal isso.

JSON também é ubíquo. Toda linguagem tem um parser JSON de biblioteca padrão. Browsers o analisam nativamente. Bancos de dados como PostgreSQL têm colunas JSON nativas. É o formato de mínimo denominador comum para troca de dados entre sistemas que não compartilham um runtime.

O que JSON erra para configuração

JSON não tem sintaxe para comentários. Esta é uma decisão de design deliberada de Douglas Crockford (o criador do JSON), com o argumento de que comentários em formatos de dados encorajam as pessoas a colocar diretivas de análise neles, o que corrompe a portabilidade do formato.

Esse é um bom princípio para respostas de API. É um problema sério para arquivos de configuração. Arquivos de configuração precisam de comentários. Você precisa explicar por que timeout_ms é 30000 e não 10000. Você precisa marcar quais campos são seguros para alterar. Você precisa deixar uma nota que diga "não defina isso acima de 100 em staging."

As alternativas são todas ruins. Alguns times usam campos "_comment". Alguns usam JSON5 (um superset com comentários) e torcem para que suas ferramentas o tratem. Alguns usam JSONC (JSON com Comentários, popularizado pelo settings.json do VS Code). Nenhum desses é JSON padrão.

JSON também é verboso para configuração. Vírgulas finais não são permitidas, causando erros de sintaxe constantes ao reordenar campos. Toda chave de string requer aspas duplas. Não há sintaxe de string multilinha — um longo comando shell precisa ser escapado em uma linha.

JSON pertence em: respostas de API, troca de dados entre serviços, manifests de pacotes que são principalmente escritos por máquinas (package.json, composer.json), e em qualquer lugar onde você precise de consistência de análise garantida entre sistemas heterogêneos.

Você pode validar JSON online para detectar erros de sintaxe antes de chegarem à sua aplicação — o que importa mais do que você pode esperar, pois uma única vírgula faltante ou colchete sobrando quebra completamente um parser JSON.


YAML: Poder e Perigo

YAML (YAML Ain't Markup Language) foi projetado para ser a alternativa amigável para humanos ao XML. É expressivo, legível e amplamente usado em ferramentas DevOps. Também é o formato de configuração mais perigoso em uso comum.

O que YAML faz certo

YAML permite comentários (#). Ele infere tipos de valores sem aspas, então você pode escrever port: 5432 em vez de "port": 5432. Suporta strings multilinhas com sintaxe limpa semelhante a heredoc. É conciso: o recuo substitui chaves e colchetes.

database:
  host: localhost
  port: 5432
  ssl: true
 
allowed_origins:
  - https://example.com
  - https://api.example.com
 
# Este é um comentário explicando por que o timeout é alto
timeout_ms: 30000

Para configurações de CI/CD — GitHub Actions, GitLab CI, CircleCI — a capacidade do YAML de expressar estruturas aninhadas de forma limpa, com comentários, é genuinamente útil. Um arquivo de workflow do GitHub Actions frequentemente abrange centenas de linhas com condições aninhadas, estratégias de matrix e blocos de variáveis de ambiente. JSON seria ilegível. TOML seria inconveniente para estruturas profundamente aninhadas.

Os footguns do YAML

A inferência de tipos do YAML é onde as coisas dão errado. O parser olha para valores sem aspas e decide qual tipo eles são. As decisões que ele toma nem sempre são as que você espera.

O Problema da Noruega. Em YAML 1.1 (que é o que a maioria dos parsers implementa — não YAML 1.2), um NO simples é analisado como o booleano false. O mesmo vale para no, No, n, N, false, False, FALSE, off, Off e OFF. Uma lista de códigos de países ISO 3166-1 inclui NO para a Noruega. Um arquivo de configuração com uma lista de códigos de países silenciosamente transformará a Noruega em false.

# YAML 1.1 — o que o parser realmente vê
country: NO        # → false (booleano)
enabled: yes       # → true (booleano)
mode: on           # → true (booleano)
debug: off         # → false (booleano)

A correção é colocar aspas em tudo que deve ser uma string: country: "NO". Mas todo o apelo do YAML é que você não precisa colocar aspas. Exigir aspas para evitar surpresas erode a vantagem de legibilidade do formato.

Inteiros octais. Em YAML 1.1, um número começando com 0 é tratado como octal. Permissões de arquivo são comumente escritas em octal: chmod: 0755. Um parser YAML lê 0755 como o número decimal 493, não 755. Isso quebrou scripts de deployment reais.

# YAML 1.1 — interpretação octal
file_mode: 0755    # → 493 (equivalente decimal do octal 0755)

Ambiguidade de strings multilinhas. YAML oferece múltiplas sintaxes de strings multilinhas — bloco literal (|), bloco dobrado (>), e inline. Elas se comportam diferentemente em relação a quebras de linha, espaços em branco finais e recuo. Escolher o errado silenciosamente produz a string errada.

# Bloco literal — preserva quebras de linha
command: |
  npm install
  npm run build
 
# Bloco dobrado — quebras de linha se tornam espaços (útil para texto longo)
description: >
  Esta é uma descrição longa que será
  dobrada em uma única linha com espaços.

Tabs vs espaços. YAML não permite caracteres de tabulação para recuo. Um editor que insere tabs silenciosamente produzirá um erro de análise — ou pior, uma análise diferente dependendo da configuração de tabulação.

YAML 1.2 corrigiu muitos desses problemas (incluindo a lista de valores booleanos), mas a maioria das ferramentas ainda implementa a 1.1. Quando você usa YAML, está escrevendo para o parser que sua toolchain acontece de ter, que pode ou não corresponder às suas suposições.


TOML: Projetado para Configuração

TOML (Tom's Obvious Minimal Language) foi criado em 2013 por Tom Preston-Werner (co-fundador do GitHub) especificamente para ser um formato de arquivo de configuração que humanos podem escrever e máquinas podem analisar sem ambiguidade.

O que TOML faz certo

TOML tem tipos explícitos e inequívocos. Uma string está sempre entre aspas. Um número é sempre um número. Um booleano é sempre true ou false (minúsculas, sem aliases). Não há inferência de tipo de valores sem aspas, então não há Problema da Noruega.

[database]
host = "localhost"
port = 5432
ssl = true
 
allowed_origins = [
  "https://example.com",
  "https://api.example.com",
]
 
# Este é um comentário explicando por que o timeout é alto
timeout_ms = 30000

TOML tem suporte de primeira classe para datas e horas (publishedAt = 2026-04-04), que JSON e YAML deixam como strings que as aplicações analisam por conta própria.

Cabeçalhos de seção ([database], [[servers]]) são explícitos e legíveis. Chaves com pontos (database.host = "localhost") permitem expressar valores aninhados inline. Array de tabelas ([[servers]]) oferece uma sintaxe limpa de lista de objetos.

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

A especificação TOML é precisa e versionada. Todo parser TOML compatível produz o mesmo resultado para a mesma entrada.

Onde TOML Fica Aquém

TOML funciona bem para aninhamento de raso a moderado. Para estruturas profundamente aninhadas — do tipo que aparecem em manifests do Kubernetes ou playbooks do Ansible — a sintaxe de cabeçalho de seção se torna repetitiva. O aninhamento baseado em recuo do YAML escala mais naturalmente para seis ou sete níveis de profundidade.

TOML também tem menos suporte de ferramentas que JSON ou YAML. A maioria das linguagens tem excelentes bibliotecas TOML, mas o suporte do editor (destaque de sintaxe, validação, autocompletar) é menos consistente que o do JSON.


Tabela Comparativa

RecursoJSONYAMLTOMLINI
ComentáriosNãoSim (#)Sim (#)Sim (; ou #)
Tipos explícitosSimNão (inferidos)SimNão (tudo strings)
Strings multilinhasNão (apenas escape)Sim (múltiplas sintaxes)Sim (""")Não
Estruturas aninhadasSim (verboso)Sim (conciso)Sim (moderado)Apenas um nível
Risco de ambiguidade de análiseBaixoAltoMuito baixoMédio
Escrita por humanosMédiaAltaAltaAlta
Geração por máquinaExcelenteBoaBoaFraca
Usos comunsAPIs, manifestsCI/CD, orquestraçãoConfig de projetoConfig de app legado

O Framework de Decisão

Uma vez que você remove a linguagem de marketing, a escolha se resume a três perguntas.

Isso é principalmente gerado por máquina ou escrito por humanos?

Se o arquivo é gerado por código e consumido por código — uma resposta de API, um artefato de build, uma entrada de cache serializada — use JSON. É o mais portável, o mais analisável, e o suporte de ferramentas é universal. Você não precisa de comentários em um arquivo que nenhum humano lê. Comprimindo esses arquivos JSON antes de transferi-los pela rede pode reduzir significativamente o tamanho do payload.

Se um humano escreve e edita este arquivo regularmente — uma configuração de projeto, uma descrição de ambiente, um manifest de ferramenta — comentários são inegociáveis. Isso descarta o JSON puro.

Você controla a toolchain?

Se você está preso em um ecossistema que impõe um formato — Kubernetes requer YAML, GitHub Actions requer YAML, Cargo requer TOML, package.json é JSON — não há decisão a tomar. Use o que o ecossistema espera.

Se você está projetando uma nova ferramenta ou um novo arquivo de configuração do zero, você tem uma escolha real.

Quão profundo é o aninhamento, e quão tolerante é sua equipe a bugs sutis?

YAML é expressivo mas frágil. Uma equipe que escreve YAML cuidadoso, coloca aspas em todas as strings, roda um linter e entende a distinção entre 1.1 e 1.2 pode usá-lo com segurança. Uma equipe que se move rapidamente, tem configurações de editor diversas e não roda linting de YAML no CI eventualmente encontrará um Problema da Noruega ou um bug octal em produção.

TOML é a escolha mais segura para configuração escrita por humanos quando você controla o formato. Tipos explícitos significam que o erro do parser aparece no tempo de análise, não no tempo de execução quando a Noruega se tornou false e a lógica do seu feature flag silenciosamente falha.

Referência rápida

  • Resposta de API ou troca de dados entre serviços: JSON
  • Manifest de pacote (principalmente escrito por máquinas): JSON
  • Kubernetes, Docker Compose, GitHub Actions, Ansible: YAML (não é uma escolha)
  • Novo arquivo de configuração de projeto que você está projetando: TOML
  • Projeto Rust: TOML (Cargo.toml)
  • Projeto Python: TOML (pyproject.toml)
  • Configuração de aplicativo legado com necessidades simples de chave-valor: INI (ou migrar para TOML)

Validando seus Arquivos de Configuração

Erros de sintaxe em arquivos de configuração são alguns dos bugs mais frustrantes para diagnosticar — a aplicação falha ao iniciar, a mensagem de erro é críptica e o erro é um único caractere mal colocado.

Para JSON, você pode validar e formatar JSON online para detectar erros imediatamente. Colar um arquivo de configuração JSON em um validador antes de fazer commit leva cinco segundos e previne uma classe de falhas de CI. Para workflows JSON mais aprofundados — minificar para produção, comparar mudanças de config entre ambientes — veja nosso guia sobre como validar, minificar e formatar JSON.

Para YAML, yamllint é o linter CLI padrão. Executá-lo no CI não é opcional se sua equipe escreve YAML de produção. Para TOML, a maioria dos ecossistemas de linguagem inclui um validador integrado (cargo check valida Cargo.toml implicitamente; python -c "import tomllib; tomllib.load(open('pyproject.toml', 'rb'))" valida qualquer arquivo TOML diretamente).


O Formato é um Contrato

Qualquer que seja o formato que você escolher, ele se torna um contrato com todo desenvolvedor e ferramenta que toca seu projeto. Mudá-lo depois é doloroso — não impossível, mas doloroso. A migração de setup.cfg e setup.py para pyproject.toml no ecossistema Python levou anos e ainda não está completa.

Escolha deliberadamente. JSON quando máquinas são o consumidor principal e portabilidade é crítica. YAML quando o ecossistema o exige ou quando estruturas profundamente aninhadas precisam ser legíveis. TOML quando humanos escrevem o arquivo, a correção importa, e você quer que o parser detecte ambiguidade no momento da leitura em vez de surgir como um bug de runtime seis meses depois.

O formato de configuração não é apenas um formato de arquivo. É uma declaração sobre quem edita o arquivo, quais ferramentas o processam e quanto você confia na coerção de tipos implícita. Faça essa declaração de propósito.


Precisa validar um arquivo de configuração JSON agora? Experimente o FileCrank JSON Viewer — cole seu JSON, detecte erros instantaneamente e formate-o para legibilidade.