Formatador, validador e visualizador de JSON online
Uma caixa de entrada e três respostas: o JSON reindentado, a árvore navegável e o veredito da validação. Você cola o texto uma vez e escolhe como quer olhar para ele, sem trocar de ferramenta no meio do caminho.
JSON em trinta segundos
JSON é um jeito de escrever dados que tanto uma pessoa quanto um programa conseguem ler. Ele tem duas caixas e nada além disso. O objeto, escrito entre chaves, guarda pares de nome e valor. O array, escrito entre colchetes, guarda uma lista em ordem.
Dentro do objeto, cada par é uma chave e um valor separados por dois-pontos. A chave é sempre um texto entre aspas duplas, sem exceção. Os pares são separados por vírgula, e o último par não leva vírgula nenhuma. É justamente essa vírgula sobrando que quebra a maioria dos JSONs escritos à mão.
Objeto dentro de objeto, array dentro de array, array dentro de objeto: dá para aninhar quanto você quiser. É essa hierarquia que a indentação desenha, e é por isso que um JSON indentado é tão mais fácil de ler que o mesmo JSON em uma linha só.

Os seis tipos, e só eles
Um valor em JSON só pode ser uma de seis coisas: texto, número, verdadeiro ou falso, null, objeto ou array. Não existe uma sétima opção, e é isso que torna o formato tão simples de implementar em qualquer linguagem.
Repare no que não está na lista: data. Quando você vê 2024-03-01 dentro de um JSON, aquilo é um texto. Quem entende que ali tem uma data é o seu código, não o formato. Vale o mesmo para dinheiro, que aparece ora como número, ora como texto, dependendo de quem escreveu a API.
null também merece atenção. Ele quer dizer que o campo existe e está vazio de propósito, o que é diferente do campo simplesmente não aparecer no documento. Muita regra de negócio depende dessa distinção.

Uma entrada, três respostas
O texto que você cola passa por JSON.parse e volta por JSON.stringify com indentação de dois espaços. Não existe botão de formatar: a saída acompanha a digitação, e a mesma leitura que produz o texto formatado alimenta a árvore e a validação.
Por isso a validação não é uma aba separada. Ela é o estado da entrada, mostrada na faixa embaixo do editor: JSON válido com o tamanho e a contagem de chaves, ou a linha e a coluna exatas do erro com uma explicação em português e, quando dá, o botão de corrigir.
Enquanto o texto está quebrado, o painel da direita não fica vazio: ele segura o último resultado válido, apagado, para você não perder a referência do que estava lendo. Assim que o JSON volta a fechar, a saída acende de novo.
Nada do que você cola aqui sai do seu navegador. O processamento é todo local, em JavaScript, sem envio para servidor, sem log e sem armazenamento.
Por que um JSON quebra
Quase todo JSON inválido cai em um punhado pequeno de erros, e quase sempre pelo mesmo motivo: alguém escreveu à mão, ou colou um objeto de JavaScript achando que era JSON. Os quatro mais comuns estão na imagem abaixo, com a versão que falha em cima e a que funciona embaixo.
A regra que resume os quatro é curta. JSON é um formato de dados, não é código. Ele não tem comentário, não aceita vírgula depois do último item, não aceita aspas simples e não conhece undefined. Se o texto parece código, provavelmente é código, e o parser vai recusar.
Quando o erro aparece, ele vem com linha e coluna. Vá até essa linha, mas olhe também a de cima: falta de vírgula ou de fechamento só é percebida pelo parser na linha seguinte, que é onde ele desiste. O erro está apontado onde a leitura travou, não necessariamente onde você digitou errado.

O que a correção automática resolve
Aspas simples no lugar de duplas, vírgula sobrando antes de fechar chave ou colchete, comentários no estilo // e /* */, e chaves ou colchetes que ficaram abertos. São os erros que aparecem quando alguém escreve JSON à mão ou cola um objeto JavaScript achando que é JSON.
A correção é uma sugestão, não uma imposição: o botão só aparece quando a ferramenta consegue reconstruir um JSON válido, e o resultado substitui a entrada para você conferir antes de copiar. Em caso de ambiguidade ela prefere não adivinhar e devolve só o erro apontado.
JSON não é JavaScript
A confusão mais comum vem daí. Na RFC 8259 as chaves são sempre strings entre aspas duplas, não existe comentário, não existe vírgula final e não existem valores como undefined, NaN ou Infinity. Um objeto que roda no console do navegador pode perfeitamente ser um JSON inválido.
Existem dialetos que relaxam essas regras, como JSON5 e JSONC, esse último o que o VS Code aceita em tsconfig.json e settings.json. Eles são convenientes, mas não são JSON: uma API que recebe JSON5 vai recusar.
Do texto para a árvore
Ler JSON como texto obriga você a contar chaves e colchetes de cabeça para saber em que nível está. A árvore faz essa conta por você. Cada objeto e cada array vira um nó que abre e fecha, e a indentação deixa de ser algo que você interpreta e passa a ser algo que você navega.
A tradução é direta. Cada campo do objeto vira um filho com o nome do campo. Cada item do array vira um filho também, só que o nome dele é a posição, começando do zero. É exatamente a mesma contagem que você usaria no código para pegar aquele item, então o caminho que você lê na árvore é o caminho que você escreve.
Valores simples, como texto e número, são folhas: não abrem, porque não têm nada dentro. Só objeto e array abrem. Quando um nó não expande, é porque você chegou no valor final.

Dois modos de leitura da árvore
O modo de valores mostra o conteúdo real de cada campo. O modo de estrutura esconde os valores e mostra só os tipos, colapsando arrays homogêneos em uma linha, por exemplo string[] no lugar de trezentas strings repetidas. O segundo modo é o que responde rápido a pergunta que aparece quando você recebe uma API nova: qual é o formato disso?
Na prática, o modo de estrutura é um esquema inferido do documento. Ele não substitui um JSON Schema escrito, porque só enxerga o que está naquele exemplo, mas serve para escrever o schema depois, ou para comparar duas respostas e achar o campo que apareceu.
Documentos grandes
Expandir tudo de uma vez em um JSON muito grande trava a aba, então acima de um limite a ferramenta pede que você abra os nós manualmente. A contagem de nós usa saída antecipada, ou seja, ela para de contar assim que sabe que o documento é grande, sem varrer a árvore inteira.
A leitura que acompanha a digitação também tem freio: ela roda em prioridade baixa, então colar alguns megabytes atrasa a saída por um instante em vez de travar a tecla. Acima de duzentos mil caracteres o texto formatado sai sem cores, porque dezenas de milhares de elementos coloridos custam mais do que ajudam.
O que a especificação garante e o que não garante
A RFC 8259 define seis tipos e nada além disso: objeto, array, string, número, booleano e null. Não existe data, não existe inteiro versus decimal, não existe comentário. Data em JSON é convenção, quase sempre uma string no formato da RFC 3339, e quem interpreta é a sua aplicação.
A especificação também não obriga a preservar a ordem das chaves nem proíbe chave repetida, e cada linguagem resolve isso de um jeito. Em JavaScript a última repetida vence, silenciosamente. Vale saber disso antes de culpar a API.
Números são outro ponto cego: a RFC não define precisão. Um id de 64 bits que cabe em Java perde precisão ao ser lido por JSON.parse, porque o number do JavaScript é ponto flutuante de 53 bits significativos. É por isso que APIs sérias mandam id grande como string.
Sintaxe válida não é dado correto
Validar aqui é verificar sintaxe. Um JSON pode estar perfeitamente bem formado e ainda assim faltar um campo obrigatório, trazer um número onde a aplicação espera string ou usar um enum que não existe. Essa segunda camada é trabalho de JSON Schema, que descreve o formato esperado e valida contra ele.
Perguntas frequentes
O que é JSON, explicado de forma simples?
É um formato de texto para guardar e trocar dados. Ele usa chaves para agrupar pares de nome e valor, e colchetes para listas. Qualquer linguagem de programação lê e escreve JSON, e é por isso que quase toda API usa esse formato.
Qual a diferença entre objeto e array em JSON?
O objeto, entre chaves, guarda campos com nome, então você busca pelo nome do campo. O array, entre colchetes, guarda uma lista em ordem, então você busca pela posição, começando do zero. Um usuário é um objeto; uma lista de usuários é um array de objetos.
Preciso clicar em algo para formatar ou validar?
Não. A saída acompanha a digitação e a validação fica sempre visível embaixo do editor, com JSON válido ou a linha e a coluna do erro. As abas formatado e árvore só trocam a forma de olhar o mesmo documento.
A ferramenta altera meus dados?
Não. A formatação só muda espaço em branco e indentação: chaves, valores e tipos continuam os mesmos, porque o texto é reserializado a partir do objeto que foi lido. A árvore é só leitura. A única ação que reescreve a entrada é a correção automática, e ela depende de você clicar.
Ele valida contra um JSON Schema?
Não. A validação aqui é de sintaxe, não de esquema. Ela garante que o texto é um JSON bem formado, não que ele tem os campos e tipos que a sua aplicação espera. Para isso existe o JSON Schema.
Posso colar um objeto JavaScript?
Pode, e é exatamente para isso que serve a correção automática. Aspas simples, comentários e vírgula final são convertidos para JSON válido quando a conversão não é ambígua.
Por que meu tsconfig.json não valida?
Porque ele quase sempre é JSONC, o dialeto com comentários que o VS Code aceita. É válido para o VS Code e inválido como JSON. A correção automática remove os comentários e devolve JSON puro.
Dá para ver só a estrutura, sem os valores?
Sim, é o modo de estrutura da árvore. Ele substitui cada valor pelo seu tipo e agrupa arrays de primitivos homogêneos em uma entrada só, o que deixa o formato do documento visível em poucas linhas.
O modo de estrutura serve como JSON Schema?
Serve como ponto de partida, não como substituto. Ele descreve o exemplo que você colou, então campo opcional ausente naquela resposta simplesmente não aparece. Use como rascunho e complete à mão.
Funciona com JSON muito grande?
Sim, com o limite prático da memória da aba. Arquivos de alguns megabytes funcionam. Acima de um certo tamanho a árvore deixa de expandir tudo de uma vez e pede que você abra os nós manualmente, porque expandir milhares de nós é o que trava o navegador.
Meu JSON é confidencial. Posso usar?
Pode. Tudo roda inteiramente no seu navegador e nenhum byte é enviado para servidor. Você pode conferir desligando a rede depois de carregar a página: a ferramenta continua funcionando.
Por que meu id numérico grande fica errado depois de formatar?
Porque o number do JavaScript guarda 53 bits significativos. Um id de 64 bits é arredondado ao ser lido. Não é a formatação que corrompe, é a leitura. A solução do lado da API é trafegar o id como string.
Referências
- RFC 8259 (The JavaScript Object Notation Data Interchange Format)A especificação vigente do JSON, e a referência que decide o que é sintaxe válida.
- json.org (em português)A gramática do formato em diagramas, útil para entender o que é e o que não é válido.
- MDN: JSON.parse()Comportamento exato do parser usado por esta ferramenta, incluindo o reviver.
- JSON SchemaA camada seguinte: validar campos, tipos e obrigatoriedade, não só sintaxe.