AO

tool · live · runs on your machine

JSON Formatter & Validator

Tidy, minify and check JSON — and when it is broken, be told exactly where and why.

· ·

Errors that tell you something

Most JSON formatters, when your input is broken, say "Unexpected token }" and leave you to find it. That is not the formatter being lazy — it is repeating whatever the browser's parser said, and the browsers disagree with each other about how much to tell you. Chrome gives a character offset. Firefox gives a line. Safari gives neither.

So this page does the locating itself. It runs its own scan over your text and reports the line and column, prints the offending line with a caret underneath it, and — where it can tell — names the actual mistake rather than the symptom:

Those last few are worth calling out. Half the broken JSON in the world is broken because it is not JSON at all — it is a Python dictionary, or a JavaScript object literal, pasted in by someone who reasonably expected them to be the same thing. Being told that is far more useful than being told a token was unexpected.

The parsing itself still uses the browser's own JSON.parse, which is fast and exactly correct. Only the fault-finding is ours.

Why it matters that this stays local

Think about what people actually paste into a JSON formatter: an API response they are debugging. Those routinely contain access tokens, session identifiers, internal URLs, customer records, email addresses.

Pasting that into a website means sending all of it to someone else's server, to have whitespace added. The computation is trivial and your browser can do it instantly — there has never been a technical reason to transmit it. Nothing you paste here leaves this tab, and you can confirm that in the network panel.

What else it does

Format makes JSON readable with two spaces, four spaces or tabs. Minify strips every unnecessary byte for shipping — and tells you how many bytes that saved. Sort keys alphabetically puts object keys in a deterministic order, which is the quickest way to make two structurally identical configurations actually diff cleanly.

Alongside the result you get a quick shape report: how many keys, how deeply nested, what the root type is, and the size before and after. For a large unfamiliar payload, the depth and key count often tell you more at a glance than the content does.

For machines

window.AOJson.process(text, {mode, indent, sortKeys}) -> {ok, output, error, stats} — Format or minify JSON. mode: format|minify. On failure, error carries message, line, column and sourceLine. stats carries keys, nodes, depth, rootType and byte sizes.
window.AOJson.findError(text) -> {message, line, column, sourceLine, index} | null — Locate the first structural problem in JSON text, with a human-readable explanation. Returns null when the text is well-formed.
window.AOJson.format(text, indent=2) -> string — Pretty-print JSON, returning an empty string if the input is invalid.
window.AOJson.minify(text) -> string — Minify JSON, returning an empty string if the input is invalid.

A machine-readable description lives at index.md.