JSON formatter
Beautify JSON with two spaces, four spaces or a tab, or minify it to one line — and when it will not parse, see the exact line and column that broke it.
Output will appear here
What this JSON formatter does
JSON (JavaScript Object Notation) is the most common format for moving structured data between programs — API responses, configuration files, log lines and more. It is designed to be compact, which also makes it hard to read once objects nest a few levels deep or arrive on a single line. This tool takes any JSON you paste and rewrites it two ways: beautified, with consistent indentation so the structure is obvious at a glance, or minified, stripped of every optional space so it is as small as possible to send over the wire.
It also validates as it formats. Because it parses the text before re-serialising it, invalid JSON never produces misleading output — instead you get the line and column where parsing failed, wherever it can work one out, so you can jump straight to the problem.
Beautify vs. minify — when to use each
The two modes serve opposite goals, and most workflows use both at different stages:
- Beautify when you are reading or debugging — inspecting an API response, comparing two payloads, or reviewing a config file in a pull request. Indentation turns a wall of text into a browsable tree.
- Minify when you are shipping — embedding JSON in HTML, storing it in a cookie or cache, or sending it in a request body where every byte counts. Minified JSON is byte-for-byte equivalent data, just without the whitespace.
The indentation selector (2 spaces, 4 spaces or a tab) only affects beautified output. Two spaces is the most common convention in JavaScript and web tooling; four spaces or tabs suit teams that prefer them. Whichever you pick, the result is still valid JSON — indentation is purely cosmetic.
Reading validation errors
When JSON is invalid, the tool reports the line and column of the first problem rather than a bare "invalid", except in the one case the section on where the position points describes. Engine error messages differ across browsers and often omit a position, so the location is computed independently and points at a reasonable spot to start looking. Fix the first error and re-check — a single stray character often cascades into several apparent problems.
Common JSON mistakes
JSON is stricter than the JavaScript object literals it resembles. These are the errors that trip people up most often:
- Trailing commas: a comma after the last item in an object or array is valid in JavaScript but not in JSON.
- Single quotes: JSON strings and keys must use double quotes. 'value' is invalid; "value" is correct.
- Unquoted keys: every object key must be a quoted string, so { name: "x" } must become { "name": "x" }.
- Comments: JSON has no comment syntax. // and /* */ will cause a parse error.
- Special numbers: NaN, Infinity and -Infinity are not valid JSON numbers.
- Wrong quote characters: “smart quotes” pasted from a word processor look like quotes but are different characters and will not parse.
Where the reported line and column point
The position is not where you left something out. It is where the parser first met something that cannot legally be there, and those are usually different places. In the object below, line 3 is missing the comma that should end it — and the tool reports line 4, column 3, the opening quote of the next key. Nothing was wrong until that quote arrived: the document could legally have ended after line 3, so the parser only learns of the omission when it meets something that is neither a comma nor a closing brace.
{
"id": 42,
"name": "widget"
"price": 9.99
}- A missing comma is reported at the first character of whatever comes next, which in indented JSON like the above is the following line — so read the line named together with the line above it.
- A trailing comma is reported at the closing brace or bracket: line 3, column 1 for an object whose last pair sits on line 2. The comma promises another pair and the brace is what breaks the promise.
- An unterminated string is usually reported at the end of the line it opened on rather than at the opening quote, because the next quote on a later line may close it somewhere else instead. A line break cannot appear inside a JSON string, so the break is the first character that cannot be there.
- Line 1, column 1 on a document that looks perfect usually means a byte-order mark. Some editors write one when saving as UTF-8; it is invisible, it sits before the opening brace, and JSON has no place for it.
And where the tool can work out no position at all, it reports the failure without one rather than naming a coordinate it has guessed. A confident line and column pointing at perfectly good syntax would send you looking in the wrong place, which is worse than being told only that the document does not parse.
What formatting changes, and what it keeps
For almost every document the answer is whitespace and nothing else. But the tool does not edit your text: it parses it into real values and writes those values out again, and five things do not survive that round trip. None of them is a fault in the tool — each is what the JSON specification says a number or an object is — and each is worth knowing before you paste the output back over your original.
- The same key written twice: only the last of the two survives, because an object cannot hold one key twice. RFC 8259 says software receiving an object with duplicate names behaves unpredictably, and another parser may keep the first instead, so which of the two you get is not something to rely on either.
- An integer longer than fifteen digits: JSON numbers are read as double-precision floating point, which holds every whole number up to two to the fifty-third exactly — a sixteen-digit figure — so a fifteen-digit integer always survives and a longer one may not. Paste 12345678901234567890 in and 12345678901234567000 comes out. Long database identifiers are the usual casualty: keep them as strings if you can.
- Exponent and trailing-zero forms are normalised: 1e3 comes back as 1000, and 1.50 as 1.5. That is the same number written the standard way.
- A magnitude outside what that format can hold comes back as something else entirely: 1e400 has no double-precision value and comes back as null, and 1e-400 comes back as 0. A long decimal fraction is rounded to the precision the format has, the same way a long integer is.
- An escape becomes the character it denotes: \u00e9 comes back as é, and an escaped surrogate pair as the emoji it spells. Both are the same string to any parser; one of the two spellings is simply shorter.
Key order is kept as you wrote it, with one exception worth knowing: a key that is nothing but digits, reading as a plain non-negative whole number under about four billion, is treated as an array index and comes back at the front of its object in numeric order, wherever you put it. Nothing else moves — no other key is reordered, and none is added or renamed. If any of this matters to you, minify rather than beautify and compare the result with your original character by character. That is the shortest way to see what the round trip did.
When the JSON you want is inside a string
Webhook logs, message queues and database columns very often carry a whole JSON document as a single string value, with every quote inside it escaped. The outer document is perfectly valid, so the tool beautifies it and reports it valid — and the part you came to read stays one long line of backslashes. Nothing has gone wrong: these are two documents, one wrapped inside a string of the other.
{
"event": "order.created",
"payload": "{\"id\":42,\"total\":19.99}"
}Reading it therefore takes two passes. Format the outer document here, copy what sits between the quotes of the string you want, undo the escaping, and paste the result back in. The JSON string escape / unescape tool does that middle step: its unescape direction turns \" back into " and the line back into a document this page can format. If you control whatever produced the file, the better fix is upstream — send the payload as a nested object rather than as a string, and neither pass is needed.
One object per line is not one document
Log files, API exports and streaming endpoints commonly hold one complete JSON object per line; the format is called JSON Lines, or NDJSON. Every line is valid JSON on its own, but the file is not a JSON document, because a JSON document holds exactly one top-level value and this holds several, one after another with nothing joining them.
{"level":"info","msg":"started"}
{"level":"warn","msg":"retrying"}
{"level":"error","msg":"gave up"}Paste that here and the tool reports line 2, column 1: the first object ended cleanly, and then a second one began where the document should have finished. There are two ways on from there. Format one line at a time, which is what you want when you are reading a single log entry. Or turn the file into one document — wrap the lines in square brackets and put a comma at the end of every line but the last — which is what you want when you are about to load the lot into something that expects an array.
Frequently asked questions
- Is my JSON sent to a server?
- No. Parsing, validation and formatting all happen in your browser using JavaScript. Nothing you paste is uploaded, stored or logged, so it is safe to use with sensitive payloads.
- Does formatting change my data?
- For almost every document, no: beautifying and minifying only add or remove whitespace between tokens, and the keys, values and structure come back identical. There are exceptions, every one of them a consequence of parsing your text into real values before writing it out again, and the section on what formatting changes lists them all.
- Why does it reorder or reformat my numbers?
- The tool parses JSON into real values and serialises them back, so numbers are normalised to their canonical form (for example 1e3 becomes 1000). For any number double-precision floating point holds exactly, the value is unchanged and only its spelling is standard. For a number needing more precision or more range than that format has — an integer past fifteen digits, a long decimal fraction, or a magnitude outside it altogether — the value itself moves, and the section on what formatting changes says how.
- Can it handle very large JSON files?
- It can handle large payloads, but because everything runs in the browser, extremely large files (tens of megabytes) may be slow or hit memory limits depending on your device.
- Does it preserve the order of object keys?
- Almost always, yes: key order is kept exactly as it appears in your input, and the tool sorts nothing of its own. The one exception is a key that is nothing but digits and reads as a plain non-negative whole number under about four billion — that one is treated as an array index and comes back at the front of its object in numeric order. JSON calls an object an unordered collection, so nothing is broken by it, but it is a surprise; the section on what formatting changes carries the detail.
- What is the difference between JSON and a JavaScript object?
- JSON is a text format for data interchange; a JavaScript object is an in-memory value. JSON is stricter: it requires double-quoted keys and strings, forbids trailing commas and comments, and only allows a fixed set of value types (strings, numbers, booleans, null, arrays and objects).
- Can I format JSON5 or JSONC (JSON with comments)?
- No. This tool validates strict, standard JSON. JSON5 and JSONC add comments and other conveniences that are not part of the JSON specification, so they will be reported as errors.
- Is a string or a number valid JSON on its own?
- Yes. A JSON document is any single value, so "hello", 42, true and null are each complete and valid, and this tool formats all four. It was not always so: RFC 4627 (2006) required an object or an array at the top level, RFC 7159 relaxed that in 2014, and RFC 8259 carries the looser rule today. Anything that rejects a bare value is following the older specification.
- Can I format JSON Lines or NDJSON here?
- One line at a time, yes — each line is a complete JSON document. The whole file at once, no: it is several documents rather than one, and the tool reports line 2, column 1, where the second begins. The section above on one object per line covers both ways round it.
- Why does it report line 1, column 1 on a document that looks correct?
- Almost always an invisible character before the opening brace, and almost always a byte-order mark left by an editor saving as UTF-8. It is a real character, it cannot be seen, and JSON has no place for it. Re-save the file as UTF-8 without a byte-order mark, or delete the very first character and paste again.
- Does formatting drop a duplicate key?
- Yes, and it is the one case where the output holds less than the input. A key written twice in the same object leaves only the last of the two, because the tool parses your text into real values and an object cannot hold one key twice. Which of the two survives is not portable either: RFC 8259 says software receiving such an object behaves unpredictably, and another parser may keep the first.
Related tools
- JSON string escape / unescape
Escape text for a JSON string, or read an escaped one back.
- SQL formatter
Format and beautify SQL — multiple dialects.
- XML formatter
Format XML and check it is well-formed — beautify or minify.
- CSV to JSON converter
Convert CSV to JSON and back — quoting handled properly.