What Is JSON? A Practical Guide to Reading, Writing and Fixing It
JSON is the data format the web runs on. Learn its syntax rules, the strict quirks that break parsers, minified vs beautified, and how to fix parse errors fast.
You copy an API response out of your browser’s network tab, paste it into your editor, and get one unbroken line four thousand characters long. Somewhere in there is the field you need. Or worse — your build fails with Unexpected token } in JSON at position 412 and you have no idea which of the 200 lines is actually wrong.
Both problems have the same root: JSON is trivially simple to read once it is formatted, and nearly impossible to read when it is not. Here is what the format actually is, the rules that catch people out, and how to debug it quickly.
Why JSON won
JSON — JavaScript Object Notation — is a plain-text format for structured data. It grew out of JavaScript’s object literal syntax and then spread far beyond JavaScript: REST APIs, config files, log pipelines, document databases, browser storage.
It won for unglamorous reasons. It maps directly onto data structures every language already has — an object becomes a dict or map, an array becomes a list — so there is no schema compiler in the middle. The grammar is tiny enough to learn in ten minutes, where XML brought namespaces, schemas, entities, and the endless attribute-versus-element argument. And every mainstream language ships a parser in its standard library.
The trade-off is that JSON is deliberately minimal: no comments, no date type, no binary type, no schema of its own. Those omissions cause most of the friction you will feel.
The building blocks
JSON has exactly two containers:
- Object —
{ }— an unordered set of key/value pairs. Keys must be strings. - Array —
[ ]— an ordered list of values.
And six value types: string, number, boolean (true / false), null, object, and array. That is the whole format.
{
"id": 4821,
"name": "Ada Lovelace",
"active": true,
"score": 99.5,
"manager": null,
"tags": ["engineering", "founding"],
"address": {
"city": "London",
"postcode": "W1J 9BW"
}
}
Notice what is not there. There is no date type, so dates travel as strings — use ISO 8601 ("2026-07-08T14:30:00Z") and everyone downstream will thank you. There is no binary type either, which is why file blobs get Base64-encoded before they go into a JSON field.
The strict rules people trip on
JSON looks like JavaScript, which lulls you into writing JavaScript. It isn’t. These are the rules that break real parsers:
Double quotes only. 'single' is invalid. This applies to keys and to string values alike.
Keys must be quoted. {name: "Ada"} is a valid JavaScript object and invalid JSON.
No trailing commas. [1, 2, 3,] is rejected. This is easily the most common hand-editing mistake.
No comments. There is no // and no /* */. If you need to annotate a config file, add a "_comment" key or move to a format that supports them.
Numbers are restricted. No leading +, no leading zeros, no hexadecimal, no trailing decimal point, and crucially no NaN or Infinity. Serialising those from JavaScript quietly turns them into null.
undefined does not exist. Only null.
Here is a file with four of those mistakes at once:
{
name: 'Ada', // who is this
"score": .5,
"tags": ["a", "b",],
}
And the version that actually parses:
{
"name": "Ada",
"score": 0.5,
"tags": ["a", "b"]
}
One more gotcha worth knowing: duplicate keys are not an error in most parsers. Most keep the last occurrence, but the specification does not require any particular behaviour, so two languages can disagree about the same document. Avoid them.
Minified vs beautified
Whitespace between JSON tokens carries no meaning, so {"a":1} and a nicely indented version parse to exactly the same thing. The choice is purely about the audience.
Minify for machines — API responses, queue payloads, anything crossing a network. Fewer bytes, marginally less parsing work. Compression narrows the gap but never reverses it.
Beautify for humans — anything you are reading, debugging, reviewing, or committing to Git. Formatted JSON also diffs properly: a one-field change shows up as a one-line diff instead of a rewritten mega-line.
How to read a parse error
Parse errors feel cryptic until you learn what they are really telling you.
Unexpected token } in JSON at position 412— the parser hit a closing brace where it expected a key or value. Usually a trailing comma just before it.Unexpected end of JSON input— the document is truncated, or a brace was never closed. Check the end of the file first.Unexpected token < in JSON at position 0— you did not receive JSON at all. You received HTML, almost always an error page or a login redirect. Look at the raw response, not the parser.
The critical insight: the reported position is where the parser noticed the problem, not where you made it. A brace you forgot to close on line 3 gets reported at the last character of the file. That is why re-indenting is such an effective debugging move — once the structure is visible, the mismatch usually is too.
JSON5, JSONC, and friends
Because the strictness chafes for hand-edited files, relaxed dialects exist:
- JSONC (“JSON with Comments”) allows
//and/* */. If you have editedtsconfig.jsonor VS Code settings, you have written JSONC. - JSON5 goes further: unquoted keys, single quotes, trailing commas, hex numbers, multi-line strings.
- NDJSON / JSON Lines is a convention rather than a dialect — one complete JSON value per line, which makes huge log files streamable.
Use them where a human types the file. Never emit them from an API: a standard JSON.parse rejects all of them.
Formatting and validating quickly
In a terminal, jq . data.json pretty-prints and validates in one step, jq -c . minifies, and python3 -m json.tool is available almost everywhere without installing anything.
For a quick paste-and-look, a browser tool is faster than opening a shell. The JSON Formatter beautifies, minifies, and validates in one place and runs entirely on your own device — worth knowing when the payload you are inspecting has real customer data in it. Two neighbouring jobs come up constantly: getting JSON into a spreadsheet with the JSON ⇄ CSV Converter, and translating config formats with YAML ⇄ JSON.
Quick answers
Can JSON have comments? No. Not in standard JSON. JSONC and JSON5 allow them, but generic parsers will reject them.
Is a bare string like "hello" valid JSON? Yes — the modern specification allows any value at the top level. Some older parsers insist on an object or array, so an object is still the safest thing to send.
Why does my trailing comma break everything? Because JavaScript tolerates it and JSON does not. It is the single most common hand-editing error.
How should I store a date? As an ISO 8601 string in UTC. JSON has no date type, and every other convention causes timezone arguments later.
JSON or YAML? YAML for files humans write by hand — it has comments and less punctuation. JSON for anything machines exchange, where predictability beats prettiness.
The takeaway
JSON is small on purpose. The whole grammar is two containers and six value types, and almost every error you will ever hit comes from one of a handful of strict rules: double quotes, no trailing commas, no comments, no exotic numbers. Learn to read the error position as “where the parser gave up” rather than “where the bug is”, format anything you intend to read, and most JSON problems stop being problems.