JSON formatter
Load sample Prettify is John Doe / age 30 / hobbies. JSON.parse then 2-space stringify. Standard JSON only.
Docify's JSON formatter validates, prettifies, and minifies JSON entirely in your browser using JSON.parse and JSON.stringify. Prettify, Minify, and Validate are buttons, not as-you-type. Load sample fills the compact object {"name":"John Doe","age":30,"email":"john@example.com","address":{"street":"123 Main St","city":"New York","country":"USA"},"hobbies":["reading","coding","gaming"]} and does not run Prettify, Minify, or Validate. Prettify then writes the matching 2-space JSON {
"name": "John Doe",
"age": 30,
"email": "john@example.com",
"address": {
"street": "123 Main St",
"city": "New York",
"country": "USA"
},
"hobbies": [
"reading",
"coding",
"gaming"
]
}. Validate writes that same 2-space JSON and the Valid JSON badge — it is the same stringify path as Prettify. Minify writes that same compact line. This is not the older users / Jane Smith / total leftover. It accepts standard JSON only — no comments, trailing commas, or JSON5. JSON.parse uses IEEE-754 Numbers, so integers outside ±(2^53 − 1) may change on Prettify or Minify. A complete exponent such as 1e309 overflows to Infinity; Prettify, Minify, and Validate then write null. 1e308 stays finite. 1e-324 underflows to 0. A repeated object name keeps the last value. Infinity, -Infinity, and NaN are not JSON numbers — JSON.parse rejects those tokens. A leading-zero integer such as 01 is not a JSON number either; keep padded IDs as strings. A leading or trailing decimal such as .5 or 1. is also invalid — write 0.5 or 1.0. A plus-prefixed integer such as +1 is not a JSON number; plus is only legal in an exponent (1e+2). An incomplete exponent such as 1e or 1e+ is also invalid — the exponent needs one or more digits. A hexadecimal prefix such as 0x1 is also invalid — JSON numbers are decimal only. A literal line feed or tab inside a quoted string is also invalid — write \n or \t. Newlines between tokens are still whitespace. A JavaScript-style \x or incomplete \u escape inside a quoted string is also invalid — write \u plus four hex digits. Python True, False, and None are not JSON literals — write true, false, or null. JavaScript undefined is not a JSON literal either — write null or omit the key. A trailing comma before } or ] is also invalid — write {"ok":true} or [1]. A // or /* */ comment is also invalid — JSON whitespace is only space, tab, LF, and CR. Write{"ok":true} without comments. A single-quoted string such as 'hello' or{'ok':true} is also invalid — JSON strings use only U+0022. Write {"ok":"true"}. An apostrophe inside a double-quoted string is fine. An unquoted object key such as {ok:true} or{1:true} is also invalid — RFC 8259 §4 requires a string name. Write {"ok":true}. An unquoted value such as {"ok":yes} oryes is also invalid — RFC 8259 §3 allows only false, null, true, object, array, number, or string. Write {"ok":"yes"} or{"ok":true}. Nothing is uploaded.
How it works
- Load sample fills the compact object
{"name":"John Doe","age":30,"email":"john@example.com","address":{"street":"123 Main St","city":"New York","country":"USA"},"hobbies":["reading","coding","gaming"]}and does not run Prettify, Minify, or Validate. - Prettify then runs
JSON.parsethenJSON.stringifywith 2-space indentation and writes{ "name": "John Doe", "age": 30, "email": "john@example.com", "address": { "street": "123 Main St", "city": "New York", "country": "USA" }, "hobbies": [ "reading", "coding", "gaming" ] }. Validate writes that same 2-space JSON and the Valid JSON badge. Minify writes that same compact line. This is not the olderusers/Jane Smith/totalleftover. - Minify serializes the same parsed value to one compact line. Non-ASCII letters stay characters (not \\uXXXX). Validate is the same JSON.parse then JSON.stringify(value, null, 2) path as Prettify: leftover Validate writes the matching 2-space JSON and the Valid JSON badge, or the browser parser error when the text is invalid. Load sample does not click those buttons.
JSON.parseuses IEEE-754 Numbers. Integers outside ±(2^53 − 1) may change when Prettify or Minify serializes them —9007199254740993becomes9007199254740992. Keep exact IDs as JSON strings. This page does not use BigInt.- A repeated object name keeps the last
JSON.parsevalue (ECMA-262).{"id":1,"id":2}becomes{"id":2}. RFC 8259 §4 says names SHOULD be unique and does not pick a winner. Validate still reports valid. This page does not warn or keep the first key. - JSON numbers are digit sequences (RFC 8259 §6 / ECMA-404).
Infinity,-Infinity, andNaNfail parse.JSON.stringifywould writenullfor a non-finite Number, but this page never reaches stringify for those tokens — parse rejects them first. - A complete exponent such as
1e309is a legal JSON number (RFC 8259 §6), butJSON.parse("1e309")isInfinity(IEEE-754 overflow;Number.MAX_VALUEis1.7976931348623157e+308). Prettify, Minify, and Validate then runJSON.stringify, which writesnullfor a non-finite Number, so{"n":1e309}becomes{"n":null}. Validate still reports valid.1e308stays finite.1e-324underflows to0, not null. This is not theInfinitytoken. Keep magnitudes that must survive as JSON strings. This page does not use BigInt. - JSON integers may not have a leading zero (RFC 8259 §6).
JSON.parse("01")and{"n":01}fail parse.0and0.1are valid;-01is not. This is not C-style octal. Keep padded IDs as JSON strings ("007"). - A JSON number needs an integer part, and a fraction needs digits after the point (RFC 8259 §6).
JSON.parse(".5")andJSON.parse("1.")fail parse.0.5and1.0are valid;-.5is not. This page does not accept JSON5 decimals. - A JSON number may start with minus, not plus (RFC 8259 §6).
JSON.parse("+1")and{"n":+1}fail parse.-1and1e+2are valid;+1is not. Plus is only legal in the exponent. This page does not accept JSON5 plus-prefixed numbers. - A JSON exponent needs one or more digits after
eorEand an optional sign (RFC 8259 §6).JSON.parse("1e")andJSON.parse("1e+")fail parse.1e2,1e+2, and1e-2are valid;1e-is not. - JSON numbers are decimal only (RFC 8259 §6). A
0xor0Xprefix is not allowed.JSON.parse("0x1")and{"n":0x1}fail parse.255and0are valid;0xFFis not. This page does not accept JSON5 hexadecimal numbers. - JSON strings must escape control characters U+0000–U+001F (RFC 8259 §7). A raw line feed or tab inside quotes fails parse (often “Bad control character in string literal”). Write
\nor\t.{"s":"hello\nworld"}is valid. Newlines between tokens are still whitespace, so pretty-printed objects are fine. This is not JSON Lines. - JSON string escapes are only
" \ / b f n r t"and\uplus exactly four hex digits (RFC 8259 §7).JSON.parse("\x41")fails parse (often “Bad escaped character in JSON”) — JavaScript\xNNis not JSON.JSON.parse("\u12")fails parse (often “Bad Unicode escape in JSON”).{"s":"\u00e9"}is valid. This page does not accept JS extra escapes. - JSON literals are only
true,false, andnull(RFC 8259 §3).JSON.parse("True")andJSON.parse("None")fail parse.{"ok":true}and{"ok":null}are valid. Those uppercase names are Python, not JSON.json.dumpswrites the lowercase tokens. - JSON literals are only
true,false, andnull(RFC 8259 §3).JSON.parse("undefined")and{"ok":undefined}fail parse.{"ok":null}is valid.undefinedis JavaScript, not JSON.JSON.stringifywould omit that key, but parse rejects the token first. - A JSON object or array may not end with a comma (RFC 8259 §4 / §5).
JSON.parse('{"ok":true,}')andJSON.parse("[1,]")fail parse.{"ok":true}and[1]are valid; empty{}and[]are valid. This page does not accept JSON5 trailing commas. - JSON whitespace is only space, tab, line feed, and carriage return (RFC 8259 §2). There is no comment syntax.
JSON.parse("// comment")andJSON.parse("/* x */ {}")fail parse.{"ok":true}and{"s":"// note"}are valid — slashes inside a string are not comments. This page does not accept JSON5 or JSONC comments. - JSON strings begin and end with U+0022 (RFC 8259 §7). A single quote (U+0027) is not a delimiter.
JSON.parse("'hello'")andJSON.parse("{'ok':true}")fail parse.{"ok":"true"}and{"s":"it's fine"}are valid — an apostrophe inside a double-quoted string is not a delimiter. This page does not accept JSON5 single-quoted strings. - A JSON object member name is a string (RFC 8259 §4 / §7). An identifier or number is not a name.
JSON.parse("{ok:true}")andJSON.parse('{ok:"true"}')fail parse.JSON.parse("{1:true}")fails too.{"ok":true}is valid. This page does not accept JSON5 unquoted keys. - A JSON value is only false, null, true, object, array, number, or string (RFC 8259 §3). An identifier is not a value.
JSON.parse('{"ok":yes}')andJSON.parse("yes")fail parse.JSON.parse("[ok]")fails too.{"ok":"yes"}and{"ok":true}are valid. This page does not accept YAML or unquoted identifiers.
FAQ
- Does this formatter upload my JSON?
- No. Parsing, formatting, minifying, Load sample, and copy run in your browser with JSON.parse and JSON.stringify. The page does not send the text to a server.
- What does Load sample Prettify write?
- Load sample fills the compact object {"name":"John Doe","age":30,"email":"john@example.com","address":{"street":"123 Main St","city":"New York","country":"USA"},"hobbies":["reading","coding","gaming"]} and does not run Prettify, Minify, or Validate. Prettify then writes the matching 2-space JSON. Validate writes that same 2-space JSON and the Valid JSON badge — it is the same JSON.parse then JSON.stringify(value, null, 2) path. Minify writes that same compact line. This is not the older users / Jane Smith / total leftover. Standard JSON only — no comments, trailing commas, or JSON5.
- What JSON dialect does this tool accept?
- Standard JSON only (ECMA-404 / RFC 8259). Keys and strings must use double quotes. Trailing commas, comments, single quotes, and JSON5 are rejected by JSON.parse.
- What is the difference between Prettify, Minify, and Validate?
- Prettify pretty-prints with 2-space indentation via JSON.stringify. Minify serializes to a single compact line. Non-ASCII letters stay characters (not \uXXXX); an input \u00e9 becomes é. Validate is the same JSON.parse then JSON.stringify(value, null, 2) path as Prettify: it writes the matching 2-space JSON and the Valid JSON badge, or the browser parser error if the text is invalid. Load sample fills the compact John Doe object and does not run any of those buttons.
- Can I format JavaScript object literals?
- No. Unquoted keys, single quotes, trailing commas, functions, and undefined are not JSON. Convert the text to strict JSON first.
- Why does JSON Lines / NDJSON fail Validate?
- JSON.parse accepts one JSON text. JSON Lines (also called NDJSON or JSONL) is one value per line (jsonlines.org). Pasting {"id":1}\n{"id":2} parses the first object and then throws, usually “unexpected non-whitespace character after JSON”. This page does not split lines. Wrap records in a JSON array if you need one parse — that is a different document. Nothing is uploaded.
- Why did my large JSON number change after Prettify?
- JSON.parse converts each JSON number to a JavaScript Number (IEEE-754 binary64; ECMA-262). Exact integers end at Number.MAX_SAFE_INTEGER, 9007199254740991 (2^53 − 1). JSON.parse("9007199254740993") is 9007199254740992; JSON.stringify then writes that even value. RFC 8259 §6 expects interoperability in that binary64 range. Validate, Prettify, and Minify all take this parse path. Keep IDs that must stay exact as JSON strings. This page does not parse numbers as BigInt. Nothing is uploaded.
- Why did a duplicate key disappear after Prettify?
- JSON.parse keeps the last value when an object repeats a name (ECMA-262 InternalizeJSONProperty). JSON.parse('{"id":1,"id":2}') is {id: 2}; Prettify and Minify then write only that last pair. Validate still reports valid. RFC 8259 §4 says names SHOULD be unique and does not pick a winner. This page does not warn, merge, or keep the first key. Nothing is uploaded.
- Why do Infinity and NaN fail Validate?
- JSON numbers are digit sequences (RFC 8259 §6 / ECMA-404). Infinity, -Infinity, and NaN are not permitted. JSON.parse("Infinity") and JSON.parse("NaN") throw; JSON.parse('{"n":Infinity}') does too. Those tokens are JavaScript, not JSON. JSON.stringify writes null for a non-finite Number, but this page never reaches stringify for those tokens — parse rejects them first. A digit-sequence overflow such as 1e309 is different: parse succeeds and stringify writes null. Use null or a string if you need a sentinel. This page does not accept JSON5 numeric literals. Nothing is uploaded.
- Why does JSON 1e309 become null after Prettify?
- JSON.parse converts each JSON number to a JavaScript Number (IEEE-754 binary64; ECMA-262). RFC 8259 §6 allows implementations to limit range and names 1E400 as a number that may not interoperate. Number.MAX_VALUE is 1.7976931348623157e+308. JSON.parse("1e308") is 1e308 (finite). JSON.parse("1e309") is Infinity (overflow). JSON.parse("-1e309") is -Infinity. JSON.stringify writes null for a non-finite Number (ECMA-262), so {"n":1e309} Prettify, Minify, and Validate output is {"n":null}. Validate still reports valid — parse succeeded. 1E309, 1e+309, and 10e308 are the same overflow. 1.8e308 is also Infinity. 1.7976931348623157e+308 stays MAX_VALUE. A quoted "1e309" stays the string. This is not the Infinity token (JSON.parse("Infinity") throws). This is not the 9007199254740993 integer-rounding case (that stays finite). A tiny exponent such as 1e-324 underflows to 0, not null. Keep magnitudes that must survive as JSON strings. This page does not use BigInt. Nothing is uploaded.
- Why does a leading-zero number fail Validate?
- RFC 8259 §6 / ECMA-404 write integers as zero or a non-zero digit plus more digits. Leading zeros are not allowed. JSON.parse("01") and JSON.parse('{"n":01}') throw (often “Unexpected number”). 0 and 0.1 are valid; -01 is not. This is not C-style octal — 007 is not 7. Keep padded IDs as JSON strings ("007"). Nothing is uploaded.
- Why do .5 and 1. fail Validate?
- RFC 8259 §6 / ECMA-404 write number = [ minus ] int [ frac ] [ exp ]. The integer part is required; a fraction is a decimal point plus one or more digits. JSON.parse(".5") and JSON.parse("1.") throw (often “Unexpected token .” or “Unterminated fractional number”). JSON.parse('{"n":.5}') and JSON.parse('{"n":1.}') do too. 0.5 and 1.0 are valid; -.5 is not. This is not JSON5, which allows leading and trailing decimal points. Nothing is uploaded.
- Why does a plus-prefixed number fail Validate?
- RFC 8259 §6 / ECMA-404 write number = [ minus ] int [ frac ] [ exp ]. A leading plus is not allowed. Plus is only legal in the exponent: exp = e [ minus / plus ] 1*DIGIT. JSON.parse("+1") and JSON.parse('{"n":+1}') throw (often “Unexpected token +”). -1 and 1e+2 are valid; +1 is not. This is not JSON5, which allows a leading plus. Nothing is uploaded.
- Why do 1e and 1e+ fail Validate?
- RFC 8259 §6 / ECMA-404 write exp = e [ minus / plus ] 1*DIGIT. After e or E and an optional sign, one or more digits are required. JSON.parse("1e") and JSON.parse("1e+") throw (often “Exponent part is missing a number”). JSON.parse('{"n":1e}') and JSON.parse('{"n":1e+}') do too. 1e2, 1e+2, and 1e-2 are valid; 1e- is not. Nothing is uploaded.
- Why does a hexadecimal number fail Validate?
- RFC 8259 §6 / ECMA-404 write number = [ minus ] int [ frac ] [ exp ]. Digits are decimal only. A 0x or 0X prefix is not allowed. JSON.parse("0x1") and JSON.parse("0XFF") throw (often “Unexpected non-whitespace character after JSON”) because parse accepts 0 and then hits x. JSON.parse('{"n":0x1}') throws too (often “Expected ',' or '}' after property value”). 255 and 0 are valid; 0xFF is not. This is not JSON5, which allows hexadecimal numbers (0xdecaf). Write a decimal or a string. Nothing is uploaded.
- Why does a newline inside a JSON string fail Validate?
- RFC 8259 §7 / ECMA-404 require control characters U+0000–U+001F inside strings to be escaped. unescaped starts at space (%x20), so a literal line feed (U+000A) or tab (U+0009) is invalid. JSON.parse of a quoted string that contains a raw line feed throws (often “Bad control character in string literal”). {"s":"hello\nworld"} is valid. Newlines between tokens are still whitespace (RFC 8259 §2) — pretty-printed objects are fine. This is not JSON Lines. Nothing is uploaded.
- Why does a \x or incomplete \u escape fail Validate?
- RFC 8259 §7 / ECMA-404 allow only ", \, /, b, f, n, r, t, and u plus exactly four hex digits after the backslash. JSON.parse('"\x41"') throws (often “Bad escaped character in JSON”) — JavaScript \xNN is not JSON. JSON.parse('"\u12"') and JSON.parse('"\u"') throw (often “Bad Unicode escape in JSON”) because \u needs four hex digits. \' is also invalid. {"s":"\u00e9"} is valid (é after parse). This is not JavaScript string syntax. Nothing is uploaded.
- Why do True and None fail Validate?
- RFC 8259 §3 / ECMA-404 allow only the lowercase literals true, false, and null. True, False, and None are Python names, not JSON. JSON.parse("True") and JSON.parse("None") throw (often “Unexpected token T” / “Unexpected token N”). JSON.parse('{"ok":True}') and JSON.parse('{"ok":None}') do too. {"ok":true} and {"ok":null} are valid. Python json.dumps writes those lowercase tokens; a pasted dict repr does not. This page does not accept Python literals. Nothing is uploaded.
- Why does undefined fail Validate?
- RFC 8259 §3 / ECMA-404 allow only the lowercase literals true, false, and null. undefined is a JavaScript name, not JSON. JSON.parse("undefined") and JSON.parse('{"ok":undefined}') throw (often “Unexpected token u” or “is not valid JSON”). {"ok":null} is valid. JSON.stringify omits a key whose value is undefined, but this page never reaches stringify — parse rejects the token first. This page does not accept JavaScript object literals. Nothing is uploaded.
- Why does a trailing comma fail Validate?
- RFC 8259 §4 / §5 write object = begin-object [ member *( value-separator member ) ] end-object and array = begin-array [ value *( value-separator value ) ] end-array. A comma may only appear between members or values, not before } or ]. JSON.parse('{"ok":true,}') throws (often “Expected double-quoted property name”). JSON.parse("[1,]") throws (often “Unexpected token ]” or “is not valid JSON”). {"ok":true} and [1] are valid; empty {} and [] are valid. This is not JSON5 or JavaScript, which allow trailing commas. Nothing is uploaded.
- Why do comments fail Validate?
- RFC 8259 §2 / ECMA-404 allow only space, tab, line feed, and carriage return as insignificant whitespace (ws = *(%x20 / %x09 / %x0A / %x0D)). There is no comment syntax. JSON.parse("// comment") and JSON.parse("/* x */ {}") throw (often “Unexpected token /” or “is not valid JSON”). JSON.parse('{"ok":true} // note') throws after the object (often “Unexpected non-whitespace character after JSON”). {"ok":true} and {"s":"// note"} are valid — slashes inside a string are not comments. JSON5 and JSONC allow // and /* */ comments; this page does not. Nothing is uploaded.
- Why do single quotes fail Validate?
- RFC 8259 §7 / ECMA-404 write string = quotation-mark *char quotation-mark with quotation-mark = %x22 (U+0022). A single quote (U+0027) is not a string delimiter. JSON.parse("'hello'") and JSON.parse("{'ok':true}") throw (often “Unexpected token '” or “Expected property name”). JSON.parse('{"s":\'ok\'}') throws too. {"ok":"true"} and {"s":"it's fine"} are valid — an apostrophe inside a double-quoted string is not a delimiter. JSON5 and JavaScript allow single-quoted strings; this page does not. Nothing is uploaded.
- Why do unquoted keys fail Validate?
- RFC 8259 §4 / ECMA-404 write member = string name-separator value. A name is a string. RFC 8259 §7 writes string = quotation-mark *char quotation-mark with quotation-mark = %x22 (U+0022). An identifier or number is not a member name. JSON.parse("{ok:true}") and JSON.parse('{ok:"true"}') throw (often “Expected property name or '}'”). JSON.parse("{1:true}") throws too. {"ok":true} is valid. JSON5 and JavaScript allow unquoted IdentifierName keys; this page does not. Nothing is uploaded.
- Why do unquoted values fail Validate?
- RFC 8259 §3 / ECMA-404 write value = false / null / true / object / array / number / string. The only literal names are lowercase true, false, and null. An identifier is not a value. JSON.parse('{"ok":yes}') and JSON.parse("yes") throw (often “Unexpected token 'y'” or “is not valid JSON”). JSON.parse("[ok]") throws too. {"ok":"yes"} and {"ok":true} are valid. A YAML mapping such as ok: yes is not JSON — YAML 1.2 Core keeps yes as a string, and this page still rejects the identifier. This page does not accept YAML or unquoted identifiers. Nothing is uploaded.