JSON is not a JS object literal
JSON is a data interchange format and far stricter than JavaScript object literals: keys must be double-quoted, strings must use double quotes, no comments, and no trailing commas. Many errors come from pasting JS syntax straight into JSON.
The usual suspects
- Trailing comma:
[1, 2, 3,]; - Single quotes:
{'name': 1}should be double-quoted; - Unquoted keys:
{name: 1}must be"name"; - Comments: neither
//nor/* */is valid.
A fast debugging routine
- Read the error line/column — most parsers point right at it;
- Check the line above the error: a missing or extra comma is the usual root cause;
- Escape inner double quotes as
"; - When unsure, format first — clean indentation makes problems obvious.
Formatting and minifying
Format with 2-space indentation while developing, minify for transport. JSON containing sensitive data is best processed with a local tool instead of untrusted online services.
Valid vs invalid at a glance
| Part | JS object literal | Valid JSON |
|---|---|---|
| Key | {name: 1} | {"name": 1} |
| String | 'abc' | "abc" |
| Trailing comma | [1, 2,] | [1, 2] |
| Comments | // note | Not supported |
| Special values | undefined, NaN | Only null |
Code example: parse safely
// Never parse untrusted input without error handling
function safeParse(text) {
try {
return { ok: true, data: JSON.parse(text) };
} catch (e) {
// e.message usually carries a position hint
return { ok: false, error: e.message };
}
}
// Validate and format from the command line (jq)
// jq . data.json -> validate and pretty-print
// jq -c . data.json -> minify to a single line
JSON vs YAML vs TOML
- JSON: the de facto interchange standard — no comments, no multiline strings; ideal for APIs and generated config;
- YAML: readable with comments, good for hand-edited config, but indentation-sensitive with implicit typing traps;
- TOML: explicit and unambiguous — a good fit for project files such as
Cargo.tomlorpyproject.toml.
Follow-up questions
Large JSON feels slow? Minify it, project only the fields you need (jq '.items[] | {id, name}') and switch to streaming parsing if necessary. Does JSON preserve key order? The spec does not guarantee it — sort explicitly where order matters.
Real-world cases: three debugging scenarios
- "Intermittent JSON parse errors from an API": often an HTML error page or a BOM mixed into the response. Inspect the raw text, not just the console.
- "A large integer ID lost its last digits": JavaScript numbers are precise only to ~2^53, so a 19-digit order ID distorts after parsing. Fix: handle large integers as strings.
- "Adding a comment breaks it": standard JSON allows no comments, so the error is expected — do not sprinkle
//in config files.
FAQ
Does formatting or minifying change the data? No, only whitespace and indentation. Which duplicate key wins? Parsers usually take the last one — a latent bug, so catch it early. JSON vs JSON5? JSON5 allows comments, single quotes and trailing commas, but generic parsers reject it — do not feed JSON5 as JSON. How do I find the syntax error? Use a formatter/validator that reports line and column — far faster than hunting commas by eye.
Try it: JSON formatter
Large files and streaming
- Avoid loading it whole: parse multi-megabyte JSON with a streaming (SAX-style) parser rather than one
JSON.parseon the entire string; - Structure first: parse only top-level keys and array lengths to confirm the shape before deciding to process it all;
- Watch for a BOM: a UTF-8 BOM breaks direct parsing — strip it explicitly on read;
- Never edit JSON with regex: substitutions can break escaping and nesting; parse, modify, then serialise.
Formatting conventions
Agree on indentation and key ordering: two-space indent, and keys either ordered by meaning or sorted before commit so diffs are not noise. Run formatting on save or in a pre-commit hook rather than relying on memory.
Numbers and precision traps
JSON does not distinguish integers from floats — 1.0 and 1 normalise to the same value in most parsers. Identifiers and money that must be exact are easily coerced into numbers and lose precision. As a rule, send integers above 2^53 and monetary amounts as strings.