JSON Viewer & Formatter Open the tool
JSON ViewerJSON Beautifier

Online JSON Beautifier

Beautify JSON online: paste a 40 KB single line, a webhook envelope buried in backslashes, or a log file with one object per row. This page is about those awkward real-world shapes — the JSON that does not pretty print cleanly on the first try.

Beautify JSON now →

Beautify, format or prettify?

Beautify, format, prettify, pretty print — four words, one operation: putting back the line breaks and indentation a machine left out. No specification defines any of them, so every tool picked its own; if you searched for one, this is the other three as well. The genuine opposites are beautify and minify.

Before — minified, 122 bytes on one line
{"event":"invoice.paid","ts":1717243800,"data":{"id":"in_88","total":4250,"lines":[{"sku":"seat","qty":3}]},"retry":false}
After — beautified and readable
{
  "event": "invoice.paid",
  "ts": 1717243800,
  "data": {
    "id": "in_88",
    "total": 4250,
    "lines": [
      {
        "sku": "seat",
        "qty": 3
      }
    ]
  },
  "retry": false
}

How wide that indent should be — two spaces, four, or tabs — and whether to sort the keys is answered on the JSON formatter page. The rest of this page deals with input that will not become readable just by re-indenting it.

How to beautify JSON online

  1. Paste the JSONOpen the JSON viewer and paste the payload into the input panel, or drop a .json file onto the page.
  2. Beautify itPress Format or CtrlEnter. Anything that will not parse reports its failing line and column instead.
  3. Read it in the treeSwitch to the tree to collapse, filter and walk the structure, then copy or download the result.

JSON escaped inside a string

The commonest reason a payload will not become readable is that it is not one JSON document but two, nested. A service serialised an object into a string and put that string in a field of another object; the inner quotes had to be escaped to survive, so what arrives is a wall of backslashes.

Before — the payload is a string, not an object
{"id":"evt_31","payload":"{\"user\":{\"id\":1,\"name\":\"Ada\"},\"ok\":true}","received":1717243800}
After — the payload, unwrapped and beautified
{
  "user": {
    "id": 1,
    "name": "Ada"
  },
  "ok": true
}

Beautifying the outer document barely helps: to the parser payload is one token. It gets a line of its own and stays a wall of backslashes, so you have to pull the inner document out and beautify it separately.

Where double-encoded JSON comes from

  • Webhook and event envelopes — the transport carries the event as an opaque string, so it never needs to know the payload's schema.
  • Message queues and structured logs — a message body is text, so anything structured has to be serialised into it first.
  • Database TEXT columns — a document stored as text comes back as text, and an ORM re-escapes it.
  • Serialising twice by accident — calling JSON.stringify on a value that was already a string.

How to recognise it

The giveaway is a run of \" sequences inside a value, usually opening with "{\". An ordinary string needs \" only when the text really contains a quotation mark, so a dozen in a row means the value is a serialised document — and three backslashes before a quote means three levels deep.

How to unwrap it

  1. Beautify the outer document to see which field holds the escaped text.
  2. Click that value in the tree — the viewer copies the decoded string, so the backslashes are already gone.
  3. Paste it back on its own and beautify it as its own document.

When the whole payload is one quoted string rather than a field, paste it as-is: the viewer recognises a JSON string that contains JSON and offers an Unescape button. If you own the producing code, stop stringifying twice.

Unicode escapes and emoji

JSON is defined over Unicode text, and it offers two equally legal spellings for any character that is not a quote, a backslash or a control character: the character itself, or a \uXXXX escape. "café" and "caf\u00e9" are the same four-character string, so a payload that arrives like this is not broken.

{
  "city": "M\u00fcnchen",
  "note": "\u0441\u043f\u0430\u0441\u0438\u0431\u043e",
  "mood": "\ud83d\ude00"
}

A beautifier will not turn those back into München, спасибо and an emoji, and it should not: swapping escapes for literal characters rewrites the bytes of your document. The tree does make them readable, because it shows parsed values and the escapes decode on the way in.

Why the escapes are there

Python is the usual explanation: json.dumps escapes every non-ASCII character because ensure_ascii defaults to True, and ensure_ascii=False sends them through as UTF-8. JavaScript's JSON.stringify does the opposite, which is why the same object serialised by a Node service and a Python service can look nothing alike.

Surrogate pairs

A \uXXXX escape carries exactly four hex digits, which only reaches U+FFFF. Anything above that — emoji, many CJK extension characters — must be written as a UTF-16 surrogate pair: a high surrogate in U+D800–U+DBFF then a low surrogate in U+DC00–U+DFFF. U+1F600 becomes \ud83d\ude00. Two side by side decode to one character; a lone one usually means a string was cut in half by a length-based truncation upstream.

Reading a big, nested payload

Past a certain size, beautifying stops being the thing that makes JSON readable. A 40 KB line becomes three thousand lines, and scrolling three thousand lines is not comprehension. These are the moves that work.

  • Collapse everything, then open one branch. Collapse all leaves you looking at the top-level keys and nothing else, so the shape arrives in one glance.
  • Search by key name instead of scrolling. The filter box (CtrlF) keeps only branches whose keys or values match — ideal when you know the field is customer_id but not where it lives.
  • Use the JSONPath readout to record where you are. The selected node's path shows under the tree, and clicking a key copies it: $.data.lines[0].sku. Paste that into the ticket and the next person lands where you were.
  • Read the tree, not the text. A collapsed node costs one row however much is inside it, so a tree stays navigable where beautified text does not.

The JSON tree viewer page covers navigation properly: beautify to check the document is sane, then switch to the tree to find anything.

JSON Lines, NDJSON and logs

Log pipelines, bulk exports and streaming APIs often emit JSON Lines — also written NDJSON — one complete JSON value per line, with no commas between them and no brackets around the whole thing. That way a process can append one record at a time and a reader can handle one at a time.

The consequence surprises people: a JSON Lines file is not a JSON document. Paste the whole thing into a beautifier and you get a parse error at the start of line two, because the document already ended when the first value did.

{"ts":"2026-08-06T09:15:02Z","level":"info","msg":"cache warm","ms":12}
{"ts":"2026-08-06T09:15:03Z","level":"warn","msg":"retry","attempt":2}
{"ts":"2026-08-06T09:15:09Z","level":"error","msg":"upstream timeout"}

Three valid documents; zero valid documents taken together. Beautify one line at a time when you are chasing a single request ID through a log dump. Otherwise wrap the lines into an array: [ before the first record, ] after the last, and a comma at the end of every line but the last — one valid array that beautifies in a single pass.

[
{"ts":"2026-08-06T09:15:02Z","level":"info","msg":"cache warm","ms":12},
{"ts":"2026-08-06T09:15:03Z","level":"warn","msg":"retry","attempt":2},
{"ts":"2026-08-06T09:15:09Z","level":"error","msg":"upstream timeout"}
]

Two things to watch. A comma after the last record is a syntax error — the mistake everyone makes when adding commas with find-and-replace — and blank lines between records become empty elements that will not parse. Log records are also very often the double-encoded case from earlier, so you may need both moves in sequence.

Frequently asked questions

What is the difference between beautify, format and pretty print?

Nothing — all four name the same operation: putting line breaks and indentation back into JSON so a person can read it. No specification defines the terms, so different tools picked different words. The real opposites are beautify and minify.

How do I beautify JSON that is escaped inside a string?

Beautify the outer document first to see which field holds the escaped text, then copy that field's value and beautify it separately. Clicking a value in the tree copies the decoded string, so the backslashes are already gone. If the whole payload is one quoted string, the viewer offers an Unescape button.

Why does my beautified JSON show \u0441 instead of letters?

Because whatever produced it escaped every non-ASCII character. \u0441 is the Cyrillic letter с, and "caf\u00e9" is the same string as "café" — both spellings are valid JSON, so a beautifier leaves them alone. The usual cause is Python's json.dumps, which escapes non-ASCII unless you pass ensure_ascii=False.

Can I beautify JSON Lines or an NDJSON log file?

Not in one pass: a JSON Lines file is not one JSON document but one independent value per line. Either beautify a line at a time, or make it a valid array first — brackets around the whole set, and a comma at the end of every line but the last.

Does beautifying JSON change the data?

No — only the whitespace between tokens moves, so the text parses to the same value, and Unicode escapes are left as they were. The caveat is that a beautifier parses and re-serialises, so numbers return in canonical form: 1.0 comes back as 1, and an ID beyond about sixteen digits can be rounded.

Is my JSON sent to a server to be beautified?

No. The beautifier is JavaScript running in your browser: the text is parsed, indented and rendered locally, and nothing is uploaded. That makes it safe for API responses, access tokens and customer records.