Menu

Search toolsChangelog

to move to openDescribe the problem, not the tool

JSON Formatter

Validates a complete UTF-8 JSON document and rewrites only the whitespace that JSON defines as insignificant. Readable and minified output preserve key order, duplicate names, string escapes and every original number token.

A UTF-8 JSON document up to 25 MB. Its bytes stay in this browser tab.

Both choices preserve key order, duplicate keys, string escapes and the exact spelling of every JSON number.

Used only for readable output. Minified output has no indentation.

Output bytes
The exact byte length of the downloadable UTF-8 JSON file.
Input bytes
Deepest nesting level
Written as

Results are provided as-is, with no warranty of accuracy. The method and its sources are published below so you can check the working.

How it works

What this works out

JSON looks simple until a formatter changes data that was never supposed to be interpreted. The common shortcut is JSON.stringify(JSON.parse(file)). That produces tidy output, but it also passes every number through JavaScript’s binary64 Number, collapses duplicate object names to one value, and chooses new escape and exponent spellings.

This tool separates validation from rewriting. The browser’s JSON parser proves that the complete source is a conforming value. A second, deliberately smaller scanner copies the original tokens and changes only the whitespace RFC 8259 calls insignificant.

The method

RFC 8259 defines a JSON text as whitespace, one value, then whitespace. A value can be an object, array, number, string, true, false or null. The only whitespace characters in the grammar are space, tab, line feed and carriage return, and they are permitted around six structural characters:

[  ]  {  }  :  ,

That gives the formatter a narrow edit surface. Outside a quoted string those four whitespace characters can be removed. Inside a string, a space is data, and a backslash determines whether the next quotation mark ends the string or is part of it. The scanner therefore keeps two bits of state: inside a string and the previous character was an escape.

Readable mode inserts a newline and indentation after a non-empty {, [, or comma, a single space after a colon, and a newline before a non-empty closing container. Minified mode inserts nothing. Neither mode converts a primitive token into a language value.

Before you read on

Which formatter is safe for the JSON number 9007199254740993?

  • That integer is one above Number.MAX_SAFE_INTEGER and can be rounded before it is written.

  • Yes. Validation and token-preserving output are separate jobs.

  • That changes its JSON type from number to string.

Validate the document, then carry the original number token into the output. RFC 8259 permits implementations to limit numeric precision and identifies the interoperable exact-integer range around 2^53; a whitespace formatter does not need to spend that precision at all.

A worked example

The one-line source is:

{"invoice":9007199254740993,"notes":"keep  two spaces","items":[true,null]}

With Readable and 2 spaces, the downloaded file is exactly:

{
  "invoice": 9007199254740993,
  "notes": "keep  two spaces",
  "items": [
    true,
    null
  ]
}

The two spaces inside "keep two spaces" remain data. The large invoice number keeps its original digits. The deepest nesting is 2: the root object is level 1 and its array is level 2. The formula test asserts the complete output bytes, filename, MIME, byte counts and depth shown by the result panel.

Why number text and object order remain untouched

RFC 8259 permits number magnitudes and precision beyond what binary64 can hold, while noting that integers from -(2^53)+1 through (2^53)-1 are the range implementations commonly agree on exactly. A formatter that parses 9007199254740993 into binary64 may write 9007199254740992. Removing a line break never required that conversion, so this tool does not do it.

The RFC also says object names should be unique, then documents what happens when they are not: some parsers keep the last value, some fail, and some expose all duplicates. It similarly notes that libraries differ over whether member order is visible. Sorting or deduplicating may be useful in a specialised data cleanup workflow, but neither is honest under a button labelled Format.

What it does not do

It does not repair invalid JSON, quote bare object names, remove comments, accept trailing commas, sort keys, or convert JSON5. Those operations need a policy for ambiguous input. Here malformed input is reported and the original file remains untouched.

It also does not change character encoding. Interoperable JSON is UTF-8, and an initial UTF-8 BOM is accepted only because RFC 8259 allows parsers to ignore one for compatibility. To recover known UTF-16 plain text, convert the bytes first; do not ask a JSON formatter to guess what characters they meant.

How it is done

  1. Read the file as strict UTF-8. Accept and consume an initial UTF-8 byte-order mark for compatibility, but do not write one into the result.
  2. Validate the complete document as one RFC 8259 JSON value before producing an artifact. Refuse an empty file, invalid UTF-8, trailing content or malformed objects, arrays, strings, numbers and literal names.
  3. Scan the validated source while tracking quoted strings and backslash escapes. Inside a string, copy every code unit exactly; outside a string, discard only space, tab, carriage return and line feed.
  4. For readable output, insert the selected indentation after an opening container and comma, one space after a colon, and a correctly indented line before a non-empty closing container. For minified output, insert no optional whitespace.
  5. Encode the rewritten text as UTF-8, add one final line feed only when selected, and offer a new .json file. Never parse number tokens into floating-point values for output.

What it assumes

  • Formatting is not canonicalisation. Object member order, duplicate names, number spelling and string escape choices stay as authored even where another parser might normalise or collapse them.
  • JSON exchanged between independent systems is UTF-8 under RFC 8259. UTF-16 and legacy code pages belong in the separate text-encoding converter before this grammar is applied.
  • The native JSON parser is used as a strict grammar validator only. The downloadable bytes come from a token-preserving scan of the original text, not from JSON.stringify.
  • Input is capped at 25 MB. The rewrite yields every 250,000 characters so progress and Cancel remain responsive; native validation itself is intentionally left to the browser's optimised parser.

Common questions

Does the JSON file leave this device while it is formatted?

No. Strict decoding, grammar validation, whitespace rewriting and file creation happen inside a worker in this browser tab. The generated browser test supplies a real JSON file and fails if tool use sends an off-origin request.

Can formatting round an integer larger than JavaScript can represent exactly?

Not here. The validator may inspect the grammar, but the writer copies the original number characters rather than serialising a JavaScript Number. An integer such as 9007199254740993 therefore keeps every digit.

Are duplicate object names removed?

No. RFC 8259 recommends unique names for interoperability but describes inconsistent parser behaviour when duplicates exist. This formatter preserves every member in its original order so formatting does not make that product decision silently.

Does minifying remove spaces or line breaks inside a string?

No. A quoted string is copied byte-for-byte after UTF-8 decoding, including ordinary spaces and escaped control characters. Only the four JSON whitespace characters found outside a string are optional.

Will the formatter sort keys or make canonical JSON?

No. Sorting changes member order and canonicalisation also changes token spelling. This tool has one narrow promise: validate the document and change insignificant whitespace only.

Sources