Vibe Engines
YouTube

Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path

JSON Formatter & Diff

A JSON formatter, validator and diff tool. Paste JSON to validate it and pretty-print it, with clear error messages on invalid input. Paste a second document to see a key-sorted, value-level diff — so real changes stand out instead of formatting or key-order noise. Everything runs in your browser.

{
  "name": "api",
  "replicas": 2,
  "ports": [
    80,
    443
  ],
  "env": {
    "TIER": "prod",
    "DEBUG": false
  }
}
{
  "replicas": 3,
  "name": "api",
  "env": {
    "DEBUG": false,
    "TIER": "prod"
  },
  "ports": [
    80,
    8443
  ]
}

Value diff (keys sorted — only real changes shown)

{
"env": {
"DEBUG": false,
"TIER": "prod"
},
"name": "api",
"ports": [
80,
- 443
+ 8443
],
- "replicas": 2
+ "replicas": 3
}

Two everyday JSON jobs, making it readable and seeing what changed, are both easy to get subtly wrong. Paste a document into JSON A and the tool validates it and pretty-prints it. Paste a second one into JSON B and it diffs the two by value, so reordered keys and reformatting stop looking like changes.

What it computes

Validation and formatting. The input goes through the browser’s own JSON.parse, which implements the strict grammar of RFC 8259: double-quoted strings and keys, no trailing commas, no comments, and only objects, arrays, strings, numbers, true, false and null. If parsing fails, the parser’s message replaces the output. If it succeeds, the value is printed back with JSON.stringify(value, null, 2): two-space indentation, one key or element per line, keys in their original order.

The value diff. Both documents are normalized, then compared line by line:

1. parse A and B
2. sort every object's keys, at every depth (arrays keep their order)
3. print both with two-space indentation
4. find the longest common subsequence of lines
5. mark lines only in A with -, lines only in B with +

Lines present in both are kept as context, so each change appears in place. If no line differs, the tool reports the documents as identical by value.

A worked example

The default inputs describe the same service twice, in a different key order:

A  {"name":"api","replicas":2,"ports":[80,443],"env":{"TIER":"prod","DEBUG":false}}
B  {"replicas":3,"name":"api","env":{"DEBUG":false,"TIER":"prod"},"ports":[80,8443]}

Each side is pretty-printed in its own order, 12 lines apiece. For the diff, the top-level keys are sorted to env, name, ports, replicas, and the keys inside env to DEBUG, TIER. The normalized documents are 12 lines each and differ on two:

  {
    "env": {
      "DEBUG": false,
      "TIER": "prod"
    },
    "name": "api",
    "ports": [
      80,
-     443
+     8443
    ],
-   "replicas": 2
+   "replicas": 3
  }

Two real changes remain: the second port moved from 443 to 8443, and replicas went from 2 to 3. Both key-order differences vanish. A plain line diff of the same pretty-printed documents, without sorting, marks 14 lines as changed; the normalized diff marks 4.

Assumptions and limits

  • Strict JSON only. Comments, trailing commas, single quotes, unquoted keys and NaN are errors, as the standard requires, so JSONC and JSON5 files need converting first. The error wording comes from your browser and differs between Chrome, Firefox and Safari.
  • Numbers are doubles. Integers above 9,007,199,254,740,992 lose precision, so 12345678901234567890 prints as 12345678901234567000, and 1e400 becomes null. 1.0 and 1 are the same value.
  • Duplicate keys collapse. If an object repeats a key, the last value wins, without a warning.
  • It is a line diff. Adding a key after the last one also changes the trailing comma on the line before it, so that unchanged value shows as removed and re-added. Moving an element within an array shows as a removal plus an addition, because order is part of an array’s value.
  • Size. The comparison table grows with the product of the two line counts, so documents of many thousands of lines can make the page slow.

How to use the result

  • Validate before you ship a config. A parse error here is the one your service would hit at startup, and Chrome and Firefox name the line and column.
  • Compare API responses and fixtures. When a snapshot test fails or an endpoint changes after a deploy, paste the old and new bodies to see only the fields that moved.
  • Read the signs together. A - line followed by a + line is a changed value. A lone + is a new key or element, and a lone - is a removed one.
  • Identical by value is not byte-identical. Key order, whitespace and number spelling may still differ, which matters only when something downstream hashes or signs the raw text.

How it works

  • Validates and pretty-prints JSON, showing the parser error on invalid input.
  • Diffs two documents with object keys sorted, so only real changes show.
  • Preserves array order (ordered) while ignoring key order (unordered).
  • Runs fully in your browser; nothing is uploaded.

Frequently asked questions

What does formatting do to my JSON?

It parses the JSON to confirm it is valid, then prints it again with two-space indentation and one key or array element per line, keeping the original key order. If the input is invalid, the parser error is shown instead. The structure and values are kept, but the text is normalized: 1.0 prints as 1, escapes such as \u00e9 print as the character itself, a repeated key keeps only its last value, and integers beyond about 9 quadrillion lose precision. It is the fastest way to make a minified blob legible.

How is the JSON diff different from a plain text diff?

A plain text diff flags every reformatting and every key-order change as a difference, which buries the real ones. This tool first normalizes both documents: it parses them and prints them again with object keys sorted at every depth and identical indentation, then diffs the printed lines. Two objects with the same data in a different key order come out identical, so only genuine value and structure changes remain. That is usually what you want when comparing API responses, fixtures or configs.

Does key order matter in JSON?

By the JSON standard, RFC 8259, an object is an unordered collection, so {"a":1,"b":2} and {"b":2,"a":1} represent the same data. Arrays are ordered, so element order does matter. This tool sorts object keys before diffing, so key-order noise disappears, but it preserves array order, so a real reordering of a list still shows up as a change. That matches how almost every JSON consumer interprets the data.

Why does my JSON fail to validate when it looks fine?

JSON is stricter than JavaScript. The usual culprits are a trailing comma after the last item, single quotes instead of double quotes, keys without quotes, comments, and values such as NaN, Infinity or undefined, none of which RFC 8259 allows. Files that permit comments, such as JSONC or JSON5 configs, need those parts removed first. The error message comes from your browser, and Chrome and Firefox include the line and column where parsing stopped.

Why did a large number change after formatting?

The browser parses every JSON number as a 64-bit floating-point double, which holds integers exactly only up to 9,007,199,254,740,992. Larger integers are rounded, so 12345678901234567890 prints as 12345678901234567000, and a value too large for a double, such as 1e400, prints as null. Most JavaScript services parse JSON the same way, so if your data carries 64-bit IDs or exact money amounts, send them as strings.

Is my JSON sent anywhere?

No. Parsing, formatting and diffing all happen in your browser with JavaScript, and nothing is uploaded, logged or stored. That makes it safe to format or compare JSON that contains configuration, tokens, personal data or other sensitive values. The tool keeps nothing between visits either: reload the page and both inputs return to the built-in example documents.