Format and check JSON
Paste a document and it comes back indented, counted and checked. If it does not parse, the line and column that stopped the reader appear with the character marked.
How it works
JSON has a small grammar with no forgiveness in it. A document is one value: an object, an array, a string, a number, true, false or null. Objects hold double-quoted names against values, arrays hold an ordered list, and whitespace between tokens means nothing whatsoever. That is the entire specification. It fits on a postcard, and that is why every language ships a reader for it and why those readers disagree about almost nothing.
What the grammar leaves out
The exclusions cause more trouble than the rules. A comment is not JSON. A comma after the final element is not JSON. Single quotes are not JSON, NaN and Infinity are not JSON, and a number may carry neither a leading zero nor a bare decimal point. Most of those are perfectly legal JavaScript, which is where the confusion starts. The format was carved out of JavaScript literal syntax around 2001 and then frozen, so the two have been drifting apart ever since.
Config files ignore all of it. The TypeScript compiler options, the VS Code settings file and a good deal of the tooling in a modern repository accept comments and a trailing comma, a dialect usually called JSONC. The tolerant reader here parses that dialect while reporting the strict verdict separately, so a config file formats without an argument and you still find out which parts the specification would throw out.
The error message is the product
A built-in reader reports a character offset. Nobody edits text by character offset. This page converts that offset into a line and a column, prints the line, and puts a caret under the exact character, which turns a hunt through 4,000 lines into a glance at one. It also names what belonged there: a colon missing after a property name reads differently from a comma missing after a value, and a reader that knows the difference can say which it wanted.
It also separates two situations that a built-in reader runs together. An unclosed brace, half a string literal or a lone minus sign could each still become valid with more typing, so they come back as a position to carry on from rather than as a failure. A single quote where a double quote belongs can never become valid, so that one is named as a mistake. Editing text means passing through broken states, and a page that shouts at every one of them is unusable.
Duplicate keys, and who wins
Two properties sharing a name break no rule of the grammar, and the specification declines to say what a reader should do about it. Every mainstream reader keeps the last occurrence and discards the earlier ones without a murmur, so a duplicate that crept in during a merge quietly changes what a program sees. This page counts them and prints the line numbers of both, then formats the document the way a reader will take it, which means the earlier value is absent from the output.
Key order and stable diffs
Properties come out in the order they went in, with one exception worth knowing: names that look like array indices are written first, in ascending numeric order, whatever order they arrived in. Order carries no meaning, so two programs can write the same object as different bytes and a version-control diff lights up over nothing. Sorting keys at every level makes the output a function of the content alone, and on anything committed to a repository that is worth doing once and then forgetting about.
Every number is a double
A JSON number has no size limit on paper. In practice it is read into a 64-bit float, and above 9,007,199,254,740,991 the whole numbers stop being consecutive. Some large integers survive exactly and their neighbours do not: 9007199254740993 is read as 9007199254740992, silently, with no complaint from anything, while 9007199254740994 comes back untouched. Snowflake identifiers and 64-bit database keys land in that gappy range constantly. This page reports the literals whose value actually changed rather than everything above the boundary, and the fix is to carry such values as strings.
Questions
Why does my config file refuse to parse?
Because most config files are not strictly JSON. The TypeScript compiler options and the VS Code settings file both permit comments and a trailing comma, a dialect known as JSONC. Leave the tolerant reader switched on and they parse cleanly. The strict verdict beside the output still reports how many comments and trailing commas the specification would have rejected.
What happens to duplicate keys?
The last occurrence wins and the earlier value disappears from the formatted output, which is exactly what a built-in reader does. Because that change is otherwise silent, the count and both line numbers are reported above the output. If both values genuinely matter, the document wants an array rather than two properties sharing a name.
Does formatting change my data?
Indentation and line breaks carry no meaning, so re-indenting is safe. Two things do change. A duplicate key collapses to its last value, and every number is re-written from the value it parsed to, so 1.50 comes back as 1.5 and 1e3 comes back as 1000. A very large integer may also come back rounded to a nearby one, and the row above says how many did.
How large a document will it take?
The reader walks the text once in a background thread, and a few megabytes format in well under a second. Past roughly fifty megabytes the tab itself becomes the limit rather than the parser, because the original text, the parsed objects and the formatted copy all have to sit in memory together.