Code Formatting

JSON Formatter

Format, compress and validate JSON data.

Input JSON
Formatted result
Formatted result will appear here
✨ AI TypeScript Generator
Click generate to create precise TypeScript interfaces for your JSON using AI.

What is JSON Formatter?

JSON (JavaScript Object Notation) is a lightweight data interchange format. The JSON formatter beautifies or minifies JSON data, making it easier to read and debug, or more compact for transmission.

Features

  • Format: Beautify JSON with proper indentation
  • Minify: Remove whitespace for compact output
  • Validate: Check JSON syntax for errors
  • Custom Indent: Choose 2 or 4 spaces, or tabs

Use Cases

  • API Development: Format API responses for debugging
  • Configuration Files: Edit config files more easily
  • Data Analysis: Inspect JSON data structures
  • Code Review: Make JSON diffs more readable

The page hands whatever you paste to the browser's own JSON.parse, then re-serializes the value with JSON.stringify at 2 or 4 spaces and shows a compact copy in a second panel. Use it to read minified API responses, align config files before a diff, or find which character stops a malformed payload from parsing.

The output is re-serialized, not merely re-indented

Formatting is two native calls: JSON.parse builds a JavaScript value, JSON.stringify(value, null, indent) writes it back out. Nothing from your original text survives except the data, so every literal is rewritten by the serializer: 1.0 becomes 1, 1e3 becomes 1000, 25.50 becomes 25.5, and the escape \u0009 becomes \t. Numbers are IEEE-754 doubles, so 9007199254740993 (2^53+1) comes back as 9007199254740992. A literal 1e999 parses to Infinity, which has no JSON spelling, so it is written as null. Duplicate keys already collapsed during the parse, because an object can only hold one value per key.

The "Tab" entry emits one space, not a tab

The indent control is a number bound directly to the third argument of JSON.stringify, with three option values: 2, 4, and 1 for the entry labelled Tab. When that argument is a number, the serializer repeats U+0020 that many times per nesting level, so the value 1 yields a single space and never U+0009. A real tab requires passing the string "\t", which this component never does. Two further consequences of the numeric argument: the count is capped at 10, and 0 or a negative number suppresses line breaks entirely, which is exactly what the compact panel does by calling JSON.stringify(value) with no indent argument at all.

What the parser accepts that your file may not contain

RFC 8259 section 2 permits exactly four whitespace characters between tokens: U+0020, U+0009, U+000A and U+000D. A UTF-8 byte order mark (U+FEFF) is not among them, so a file saved as "UTF-8 with BOM" fails on its very first character with a message quoting something invisible. Comments and trailing commas are rejected too, even though JSONC editors such as tsconfig.json accept them. Error text is the engine's own: V8 usually appends a 0-based character offset ("... in JSON at position 7"), and for some inputs quotes a snippet instead, so expect to count characters rather than read line and column. Whitespace-only input is treated as empty and reports nothing.

Worked example

Formatting a compact record that carries three silent value changes

Input
{"orderId":9007199254740993,"amount":25.50,"retry":1e999,"status":"paid"}
Output
{
  "orderId": 9007199254740992,
  "amount": 25.5,
  "retry": null,
  "status": "paid"
}

The input is 73 bytes; the two-space output is 88 bytes across 6 lines, and the compact panel gives 71 bytes. orderId is one above 2^53-1, so it rounds down by one; 25.50 is rewritten as 25.5; 1e999 overflows to Infinity and is written as null. None of these are formatting bugs — they are the limits of the numbers JavaScript can hold.

Limits and pitfalls

  • No input size cap is implemented: the whole document goes to JSON.parse and is then syntax-highlighted on the main thread, so a multi-megabyte payload freezes the page until it finishes.
  • The indent menu only offers 2 spaces, 4 spaces, and the "Tab" entry that inserts one space; a genuine tab character or a custom width cannot be selected.
  • Strict JSON only — comments, trailing commas, single-quoted strings, NaN, Infinity and hex numbers such as 0x1f are all rejected, so JSONC files must be cleaned before they can be formatted here.
  • Repeated keys are merged by the parser before anything is displayed, so you only ever see the last value and cannot use this page to audit duplicate keys.
  • Because values round-trip through doubles, payloads full of 18-digit IDs or high-precision decimals cannot be validated for exact content here; keep such fields as strings.

Related tools

Six jobs that look like "format my JSON", and the right tool for each

What you actually needJSON formatter on this pageWhere to go instead
You only want to see the shape of a body you already havePaste the minified text: the left pane re-serializes it at 2 spaces and the lower panel keeps the compact copy, both on screen at once, and the formatting itself makes no network request.If the body still lives behind a URL, keep it in the shell — curl -s https://api.example.com/orders | jq . prints the same 2-space shape with no copy step, and the request stays in your history for the next run.
You want TypeScript interfaces for the payloadThe AI panel posts the formatted text as the prompt to the site's /ai/generate endpoint and pastes back what it returns; the button stays disabled until the text parses, so a syntax error has to be fixed before generating.quicktype or json2ts derives the interfaces locally from the same JSON — quicktype -l ts payload.json — and preserves property names character for character. Choose it when the payload cannot leave your machine or when field names must survive unchanged.
You need one branch out of a large responseBoth panes always render the whole document: there is no path box, no filter and no sort control, so a response with thousands of keys comes back just as wide as it went in.Narrow it first with jq '.items[] | select(.stock.qty < 13)', then paste only that slice here if you still want to read it at 4 spaces. Two passes beat scrolling one giant object.
Two versions of a config that have to be compared as textOutput order is whatever the parser hands back: integer-like keys come out ascending (0, 1, 2 …) ahead of the others, and the rest keep their insertion order. Formatting fixes indentation but never ordering.Use jq -S . to sort every key before printing, so diff, git diff or a checksum compares content instead of key placement. Sort for the comparison, format here only if you still have to read it.
You are checking whether the data is right, not whether it parsesA clean output means one thing only: JSON.parse accepted the text. A missing required field, a string where a number belongs, or a null where the consumer expects an array all still look perfect.A JSON Schema validator (ajv, or the schema assertion in your test suite) is what answers required/type questions. Fix syntax here; fix the contract there — they are different failures.
The same clean-up, once per commit, across a repoOne paste, one indent, one copy. Correct for a single file, wrong for a tree, where the manual step is exactly what lets indentation drift between files.prettier --write "**/*.json" rewrites every file in place and keeps them identical in style; wire it into a pre-commit hook so that nobody pastes JSON at all.

One concrete scenario

Picking an indent for a payload that is about to be committed

An orders response arrives as a single line: 853 bytes, eight records, the deepest fields three levels in. Paste it and the line count ignores the setting completely — 111 lines at one, two or four spaces — but the byte count does not: 1,356 at one space, 1,689 at two, 2,355 at four, because every line pays the indent once per level it sits at. That 666-byte spread between two and four spaces is what a reviewer scrolls past in the diff. If the file lives beside prettier-formatted JSON, take 2 spaces and commit that; if the formatted copy only has to be read in a ticket, copy from the minified panel instead, which hands the 853 bytes back unchanged.

Frequently Asked Questions

Why does my JSON fail validation even though it looks correct?
The most common causes: a trailing comma after the last item, single quotes instead of double quotes, unescaped newlines inside strings, or comments — none of these are valid JSON. The validator points to the exact line and column; fix the first error and re-run, because later errors are often cascades of the first one.
What is the difference between beautify and minify?
Beautify adds indentation and line breaks so the structure is easy to read and diff; minify strips every unnecessary byte for transport. They are lossless inverses — both parse to exactly the same data.
Is it safe to paste API responses that contain tokens?
Formatting runs entirely in your browser with JavaScript; the input never leaves your machine. Still, make it a habit to redact live credentials before sharing formatted output anywhere.

Content reviewed: