JSON Formatter & Validator

Share:

Format, validate and minify JSON instantly — with clear error messages and line numbers. Free, no signup, works entirely in your browser.

RT-DEV-002 · Developer Tools

JSON Formatter & Validator Tool

0 chars
📅 Research current as of 13 Sep 2026 · Sources: RFC 8259 (STD 90, December 2017) and ECMA-404 2nd edition for the JSON grammar, the duplicate-name rule, the interoperable number range and the unpaired-surrogate warning; ECMA-262 for the JSON.parse / JSON.stringify behaviour this page is built on
Standards, published formulas, and reference data are revised over time — check against a current authoritative source before relying on these figures.
Advertisement
After results · AD-W1 Responsive · Post-tool — peak engagement

How to Use the JSON Formatter

Paste your raw or minified JSON

Drop in any JSON string — from an API response, config file, or log output. The textarea accepts any valid or invalid JSON so errors can be detected and reported.

Choose your indent preference

Select 2 spaces, 4 spaces, or Tab to match your codebase style guide. The indent setting also applies when re-formatting — switch at any time and the output updates instantly.

Click Format to pretty-print and validate

The tool parses your JSON and highlights errors with exact positions. A green badge confirms valid JSON. A red error banner pinpoints exactly what went wrong so you can fix it immediately.

Copy or download the result

One-click copy to clipboard or download as a .json file ready to use in your project. Line numbers in the output make it easy to navigate large JSON documents.

Advertisement
After how-to · AD-W2 Responsive

JSON — The Language of Modern APIs

What this page does to your JSON

It does not reformat your text. It parses it into a value and then writes a fresh document from that value — JSON.parse followed by JSON.stringify, with your chosen indent. That is worth knowing before you paste something you intend to diff, because a round trip is not byte-preserving even when it is information-preserving, and in three cases it is not information-preserving either.

Things that change but do not matter. Escapes are resolved to the character they name: {"\u0041":"\u0042"} comes back as {"A":"B"}, and an escaped solidus a\/b comes back as a/b — both spellings are legal under RFC 8259 §7, and the output picks one. Number literals are re-spelled from their numeric value, so 1.0 becomes 1, 1e2 and 1E+2 both become 100, and -0 becomes 0. Nothing has been lost; the bytes are simply not the bytes you pasted.

Things that change and do matter. First, duplicate names. RFC 8259 §4 says the names within an object SHOULD be unique and is explicit about what happens when they are not: the behavior of software that receives such an object is unpredictable. Many implementations report the last name/value pair only. Other implementations report an error or fail to parse the object, and some implementations report all of the name/value pairs, including duplicates. This page is in the first group. Paste {"a":1,"a":2} and you get {"a":2} — a valid document, one pair shorter, with no warning. The key count in the output toolbar counts what survived, not what you pasted.

Second, large integers. JSON's grammar puts no bound on a number's magnitude, but RFC 8259 §6 notes that integers in the range [-(2**53)+1, (2**53)-1] are interoperable in the sense that implementations will agree exactly on their numeric values — and JavaScript numbers are exactly the IEEE 754 binary64 values that range describes. A 64-bit database ID such as 12345678901234567890 comes back as 12345678901234567000. The output is still valid JSON. It is a different number. The RFC also names 1E400 as a magnitude that may indicate potential interoperability problems; here it becomes null, because Infinity has no JSON spelling.

Third, member order for integer-like names. JSON object members are unordered — RFC 8259 §4 observes that JSON parsing libraries have been observed to differ as to whether or not they make the ordering of object members visible to calling software — and this page inherits ECMAScript's property order, in which keys that look like array indices come first in ascending numeric order. So {"10":"a","9":"b"} is written back as {"9":"b","10":"a"}. Names that are not canonical non-negative integers ("-1", "01") keep insertion order. If your JSON uses numeric strings as keys and you are eyeballing a diff, this is the one to watch for.

Everything runs in the page. There is no upload step, no request is made when you format, validate or minify, and the Download button builds the file locally with the Blob API.

Why valid JSON is a narrower target than it looks

JSON's grammar is small enough to fit on a page, and its strictness surprises people arriving from JavaScript or Python, where the same text is legal. What this page rejects, it rejects because RFC 8259's ABNF has no production for it:

Trailing commas. {"key":"value",} is invalid. The grammar is object = begin-object [ member *( value-separator member ) ] end-object — a separator must be followed by a member. Modern JavaScript and Python both allow the trailing comma, which is why this is the most common paste failure.

Single quotes and unquoted names. A name is a string, and a string is delimited by quotation marks (U+0022) only. {'key':'value'} and {key:"value"} are JavaScript object literals, not JSON.

Comments. There is no comment production at all. JSON5 and JSONC add one — VS Code's settings files are JSONC — but neither is JSON, and a strict parser will reject them.

NaN, Infinity and undefined. None has a JSON spelling. They will not parse on the way in, and on the way out JSON.stringify writes null for the first two and omits a member whose value is undefined entirely.

Unpaired surrogates are the exception — they are legal, and they are a known hazard. RFC 8259 §8.2 notes that the ABNF permits bit sequences that cannot encode Unicode characters; for example, "\uDEAD" (a single unpaired UTF-16 surrogate), typically produced when a library truncates a UTF-16 string without checking whether the truncation split a surrogate pair, and that the behaviour of software receiving such a value is unpredictable. This page parses it and writes it back in escaped form rather than emitting an ill-formed UTF-8 sequence, so the defect survives the round trip visibly instead of being laundered.

One more RFC 8259 note worth carrying into your own code, because it is invisible here: §8.3 warns that comparing names without resolving escapes may incorrectly find that "a\\b" and "a\u005Cb" are not equal. Two names that this page prints identically may not be equal to a comparator working on raw text.

Where a valid JSON document can still be a lossy one

01

JSON has two current standards that were written to agree: ECMA-404 (1st edition 2013, 2nd edition 2017) defines the syntax, and RFC 8259 (December 2017, Internet Standard STD 90) adds interoperability guidance on top of the same grammar.

02

Duplicate names are legal but undefined. RFC 8259 §4: names SHOULD be unique, and where they are not, the behavior of software that receives such an object is unpredictable. Paste {"a":1,"a":2} here and you get {"a":2} — last wins, silently.

03

A trailing comma is invalid, and the reason is structural rather than stylistic: the grammar is [ member *( value-separator member ) ], so a comma must be followed by a member. JavaScript and Python both allow it, which is why it is the commonest paste failure.

04

There are six value types — string, number, object, array, true/false, null — and no seventh. Dates are a convention, not a type, which is why every API argues about date formats.

05

The interoperable integer range is smaller than the grammar's. RFC 8259 §6 says only integers in [-(2**53)+1, (2**53)-1] are values implementations will agree exactly on. Paste 12345678901234567890 and this page returns 12345678901234567000 — still valid, no longer the same number.

06

The RFC names a specific literal as a warning sign: 1E400 may indicate potential interoperability problems. Here it parses without error and comes back as null, because the value overflows to Infinity and Infinity has no JSON spelling.

07

Integer-like names get reordered. {"10":"a","9":"b"} is written back as {"9":"b","10":"a"} — ECMAScript orders array-index-shaped keys numerically before the rest. RFC 8259 §4 notes libraries differ on whether member order is even visible, so this is conforming; it is still a surprise in a diff.

08

Escapes are resolved, not preserved. "\u0041" returns as "A" and "a\/b" as "a/b". Both spellings are legal under §7; the round trip picks one. §8.3 warns that a comparator working on unresolved text may incorrectly find that "a\\b" and "a\u005Cb" are not equal.

09

An unpaired surrogate is valid JSON. RFC 8259 §8.2 gives "\uDEAD" as its own example, usually created when a library truncates a UTF-16 string without checking whether the truncation split a surrogate pair. This page writes it back escaped rather than emitting ill-formed UTF-8, so the defect stays visible.

10

Parsing has been made an instruction-count problem. Langdale and Lemire's simdjson is, on its own account, the first standard-compliant JSON parser to process gigabytes of data per second on a single core, using a quarter or fewer instructions than a state-of-the-art reference parser like RapidJSON — SIMD and branchless code, not a faster grammar.

Frequently Asked Questions

  • Both buttons run the same two steps — parse your text into a value, then write a new document from that value — and differ only in the indent handed to the writer: your chosen 2 spaces, 4 spaces or a tab for Format, none at all for Minify. The two outputs therefore carry identical data. Neither is a reformatting of your input text: escapes are resolved, number literals are re-spelled from their value, and duplicate object names collapse to the last one. The next question covers the three cases where that matters.
  • In three cases, yes, and each follows from parsing rather than from a bug. Duplicate names collapse. RFC 8259 §4 says object names SHOULD be unique and that otherwise the behavior of software that receives such an object is unpredictable; this page keeps the last, so {"a":1,"a":2} becomes {"a":2} with no warning. Integers wider than 2⁵³−1 are rounded — see the large-numbers question below. Integer-like names are reordered: {"10":"a","9":"b"} is written back as {"9":"b","10":"a"}, because ECMAScript sorts array-index-shaped keys ahead of the rest. Everything else that changes is cosmetic — escapes resolved, number literals re-spelled, whitespace rebuilt — and carries the same information. If you need the original bytes preserved exactly, keep the original: a formatter's output is a new document, not an edit of yours.
  • JSON does not allow a comma after the last element in an array or object. For example, {"name": "Alice",} is invalid JSON — remove the comma after "Alice". This is a common mistake for developers used to JavaScript or Python, where trailing commas are permitted. The error message in this tool will identify the approximate character position so you can find it quickly.
  • No. RFC 8259's grammar has no comment production at all, so there is nowhere in a JSON text where // or /* */ is legal, and this page rejects a document containing either. If you need annotated configuration, JSON5 and JSONC (JSON with Comments — the dialect VS Code uses for its own settings files) both add them, and both are separate formats rather than relaxed JSON: a parser that accepts them is by definition not enforcing RFC 8259. The usual workaround inside strict JSON is a dedicated member — a "_comment" name your consumer ignores.
  • JSON is a text format derived from JavaScript object literal syntax, but it is stricter. In a JavaScript object literal, keys can be unquoted ({name: "Alice"}), strings can use single or double quotes, trailing commas are allowed, and values can be functions, undefined, or NaN. In JSON, all keys and string values must use double quotes, trailing commas are illegal, and only six value types are valid: string, number, object, array, boolean, and null.
  • JSON supports exactly six data types: string (must use double quotes), number (integer or floating-point, no quotes), object (key-value pairs in curly braces), array (ordered list in square brackets), boolean (true or false, lowercase), and null (lowercase). Dates, functions, undefined, NaN, Infinity, and binary data have no native JSON representation.
  • Because the grammar allows a number this page cannot hold. RFC 8259 §6 puts no limit on magnitude or precision in the syntax, but it does say that integers in the range [-(2**53)+1, (2**53)-1] are interoperable in the sense that implementations will agree exactly on their numeric values — and that is exactly the set of integers an IEEE 754 binary64 value represents without loss. Anything wider is rounded on the way in. A 64-bit database ID such as 12345678901234567890 comes back from this page as 12345678901234567000: valid JSON, wrong ID, no error. The same applies to 1E400, which the RFC names as a magnitude that may indicate potential interoperability problems and which arrives here as null. If your system has 64-bit identifiers, transmit them as strings — that is the only representation both ends will agree on.
  • Yes — paste the raw JSON response body directly into the input textarea and click Format. API responses are almost always minified (single-line) JSON, and formatting them makes inspecting the structure, fields, and values much easier during development and debugging. This tool runs entirely in your browser — your data never leaves your device.
  • After formatting or minifying, click the Download button in the output toolbar. The tool creates a formatted.json file and triggers your browser's standard download — no server involved. The file is generated entirely in your browser using the Blob API, so it works offline and your data remains private.
  • Yes — no account, no subscription, and no size limit beyond what your browser will hold in a textarea. The more useful half of the answer is that nothing you paste is transmitted: formatting, validating and minifying all run in the page, and the Download button assembles the file locally with the Blob API. You can confirm that from your browser's network panel, which stays empty while you work, and the page keeps working with the network disconnected once it has loaded.
  • They solve different problems, and the size difference people quote depends entirely on the document. XML closes every element by name (<name>Alice</name> against "name":"Alice"), so JSON is usually shorter for record-shaped data and the gap narrows for text with markup inside it. The structural difference matters more. JSON's six types map onto the built-in types of most languages, so a parse yields usable values directly; XML is a document model in which everything is text until a schema says otherwise. That is also XML's advantage — it has mixed content, attributes, namespaces, comments, and a mature schema and query stack (XSD, XPath, XSLT), none of which JSON has natively. Use JSON to interchange data; reach for XML when you are marking up documents or working inside an ecosystem built on it.

Related News

You may be interested in these recent stories from our newsroom.

View all news →

Method & sources

How it computes

Parses the pasted text with JSON.parse and writes a fresh document from the resulting value with JSON.stringify at the selected indent (2 spaces, 4 spaces, tab, or none for Minify). Validation is the parse step alone. It is a round trip through a value, not a reformatting of the text, so RFC 8259's three underdetermined cases — duplicate object names, integers outside the interoperable range, and member ordering — resolve the way ECMAScript resolves them.

What this tool implements

  • Accepts exactly the grammar of RFC 8259 / ECMA-404: no comments, no trailing commas, no single-quoted or unquoted names, no NaN, Infinity or undefined. Each rejection is explained on the page by the production that forbids it rather than as a house rule.
  • Duplicate names (RFC 8259 §4): the standard says names 'SHOULD be unique' and that otherwise 'the behavior of software that receives such an object is unpredictable. Many implementations report the last name/value pair only.' This page is in that group — {"a":1,"a":2} formats as {"a":2}, silently. The page states it, with the example, because a formatter is exactly where a reader would assume the opposite.
  • Numbers (RFC 8259 §6): the grammar bounds neither magnitude nor precision, but only integers in [-(2**53)+1, (2**53)-1] are 'interoperable in the sense that implementations will agree exactly on their numeric values'. Values are IEEE 754 binary64 here, so a 64-bit ID is rounded and 1E400 — the literal the RFC itself names as a warning sign — comes back as null.
  • Member ordering (RFC 8259 §4): 'JSON parsing libraries have been observed to differ as to whether or not they make the ordering of object members visible.' This page inherits ECMAScript property order, in which canonical array-index names sort numerically ahead of the rest, so {"10":"a","9":"b"} is written back reordered. Conforming, and worth knowing before a diff.
  • Strings (RFC 8259 §7): escape forms are resolved to the characters they denote, so \u0041 returns as A and a\/b as a/b. Both spellings are legal; the round trip picks one. §8.3's warning about comparing unresolved escapes is carried on the page.
  • Unpaired surrogates (RFC 8259 §8.2): legal in the ABNF, unpredictable in effect. This page parses "\uDEAD" and re-emits it in escaped form (ECMAScript's well-formed JSON.stringify), so an ill-formed string survives the round trip visibly rather than being laundered into replacement characters.

Sources

  • RFC 8259 (STD 90), The JavaScript Object Notation (JSON) Data Interchange Format, IETF, December 2017 — §4 objects and the duplicate-name rule, §6 numbers and the [-(2**53)+1, (2**53)-1] interoperable range, §7 strings and escapes, §8.2 unpaired surrogates, §8.3 string comparison: https://www.rfc-editor.org/rfc/rfc8259
  • ECMA-404, The JSON Data Interchange Syntax, 2nd edition, December 2017 (1st edition October 2013) — the syntax RFC 8259 shares: https://ecma-international.org/publications-and-standards/standar…
  • ECMA-262, ECMAScript Language Specification — JSON.parse and JSON.stringify (the well-formed stringify that escapes lone surrogates), and OrdinaryOwnPropertyKeys, which is why array-index-shaped names sort first: https://tc39.es/ecma262/
  • IEEE Std 754-2019, Standard for Floating-Point Arithmetic — binary64, the format RFC 8259 §6 names when it defines the interoperable integer range: https://doi.org/10.1109/IEEESTD.2019.8766229
  • Langdale G, Lemire D. Parsing Gigabytes of JSON per Second. The VLDB Journal 2019;28(6):941-960. https://arxiv.org/abs/1902.08318

What can make this go out of date

  • None at runtime. The page makes no network request while you format, validate, minify or download; it works offline once loaded.

Abridged — the full review record for this tool runs longer than the list above.

Advertisement
Pre-footer · AD-W3 728 × 90