A little help goes a long way. Find a tool/

Developer FIELD NOTES · 5 MIN READ

JSON Explained: The Format the Web Runs On

Six JSON value types, the strict syntax rules, pretty vs minified, the big-number precision trap, and why JSON is not JavaScript.

JSON — JavaScript Object Notation — is the language machines use to talk to each other: every REST API response, most modern config files, webhooks, log lines, and JWT payloads are JSON under the hood. The entire specification fits on roughly one page, and that smallness is exactly why it won: six kinds of values, a couple of delimiters, and almost no room for disagreement between parsers.

The whole grammar: six kinds of value

Every JSON document is a single value, and that value can only be one of six things: an object, an array, a string, a number, true/false, or null. Objects map string keys to values; arrays hold ordered values; everything else is a leaf. Nest the containers and you can express almost any data:

{
  "id": 7241,
  "name": "Ada Lovelace",
  "verified": true,
  "tags": ["math", "computing"],
  "address": { "city": "London", "postcode": null }
}

That one object uses all six kinds: a number, a string, a boolean, an array of strings, and a nested object containing null. It is worth separating null from its neighbours — it means "deliberately empty", which is different from an empty string "" (a value that happens to be blank), from 0 (a number), and from a missing key, which some languages surface as undefined. JSON has no undefined; if a key is absent, you find out by looking.

The strict rules that trip people up

JSON is forgiving about whitespace and merciless about punctuation. Four rules produce most real-world parse errors:

{ "name": 'Ada' }     ← single quotes: invalid
{ name: "Ada" }       ← unquoted key: invalid
{ "a": 1, "b": 2, }   ← trailing comma: invalid
{ "n": /* hi */ 1 }   ← comments: invalid

Keys must be double-quoted strings, string values must use double quotes, there are no trailing commas, and there is no comment syntax at all. That last one is a deliberate design decision — it keeps parsers tiny and files unambiguous — but it is also the single biggest reason hand-edited configuration moved to formats like YAML and TOML, which allow comments (compared in YAML vs TOML vs JSON).

Pretty vs minified: same data, two outfits

Whitespace between tokens is not part of the data. A parser skips spaces, tabs, and newlines outside strings, so this:

{"a":1,"b":[2,3]}

…means exactly the same as the spread-out version with one key per line. Pretty-printing (indentation, consistent spacing) is for humans reading, reviewing, and diffing files; minification — stripping every non-essential byte — is for transport and storage. A typical pretty-printed API response shrinks 70–80% when minified, which is why servers minify by default and developer tools pretty-print on demand. One exception matters: whitespace inside strings is data. "a b" keeps its double space no matter how you format the surrounding file.

Numbers, and the precision trap

The number grammar is minimal: optional minus, digits, optional fraction, optional exponent — no hex, no leading zeros, no NaN or Infinity. The trap is precision. The spec does not define how exact numbers must be, and every mainstream parser reads them into IEEE 754 double-precision floats, which represent integers exactly only up to 253 − 1 = 9,007,199,254,740,991. One above that:

9007199254740993   // what you wrote
9007199254740992   // what JavaScript parses and prints

The final digit silently vanishes. This is why APIs that issue very large numeric IDs — Twitter snowflakes, Discord IDs — deliver them as strings: "id": "175928847109932151". Quoting the ID costs nothing and guarantees it survives every JavaScript client intact. If you design an API and your IDs exceed 253, quote them.

JSON is not JavaScript — and not a regex problem

The name misleads. JSON borrowed JavaScript's literal syntax as a data format, but it is not executable JavaScript: {name: "Ada"} is a valid JS object literal yet invalid JSON (unquoted key); {'name': 'Ada'} is valid JS and invalid JSON; functions, undefined, and trailing commas exist in JS but not in JSON. Parse with JSON.parse, never eval — eval executes whatever it is handed, and JSON arriving over a network is untrusted input.

It is also not something you can match with string patterns. JSON nests — braces inside arrays inside braces — and matching nested structure is exactly what regular expressions cannot do reliably (they match flat text; see How Regular Expressions Work). The robust pipeline is always: parse first, then query the resulting structure. A regex that "works" on your test payload will meet a string containing "}"," one day and lose.

Where it shows up — and how it breaks in the wild

Beyond APIs, JSON appears in webhooks, structured log lines, JSON-LD metadata embedded in web pages, and inside JWTs, where the header and payload are Base64-encoded JSON strings (see How Base64 Encoding Works for that layer). The failures that actually fill validators' logs are mundane: "smart quotes" pasted from a word processor (“curly” instead of "straight"), a UTF-8 byte-order mark sitting invisibly before the first {, a literal line break inside a string (it must be written as the escape \n), and undefined sneaking into output built by string concatenation. A validator that reports the exact line and character of the first problem turns minutes of staring into seconds.

Try it yourself

Paste any document into the JSON Validator — it parses and reports the first error with its position, so "what's wrong here?" stops being a guessing game. Run clean documents through the JSON Formatter to pretty-print them at your preferred indentation, and through JSON Minify to strip the whitespace and see how many bytes a payload really needs on the wire.

Frequently asked questions

What are the six JSON value types?
Objects ({}), arrays ([]), strings, numbers, true/false, and null. Every JSON document is a single value of one of these kinds; everything else is built by nesting objects and arrays. There is no undefined, no functions, and no date type — dates travel as strings, usually ISO 8601.
Why does JSON not allow comments?
They were deliberately left out to keep parsers tiny and files unambiguous. The practical consequence: for hand-edited config where comments matter, formats like YAML or TOML fit better. JSONC and JSON5 add comments, but they are convenience dialects, not interoperable standards.
Why do big numbers lose precision in JSON?
The spec leaves number precision open, and mainstream parsers read numbers as IEEE 754 double-precision floats, which are exact for integers only up to 2^53 − 1 (9,007,199,254,740,991). Beyond that, low digits silently change — which is why APIs send large IDs as strings.
What is the difference between pretty and minified JSON?
Nothing in the data. Whitespace between tokens is ignored by parsers, so formatting changes size only. Pretty-printed JSON is for humans reading and diffing; minified JSON saves bandwidth in transport. Whitespace inside strings is data and is preserved either way.
Can I parse JSON with a regular expression?
Not reliably. JSON nests arbitrarily, and regex matching cannot track bracket depth — regular expressions match flat text. Parse into a data structure first with JSON.parse, then query it, and use a validator to pinpoint syntax errors instead of eyeballing patterns.