Cheatsheet

JSON Syntax Reference

# JSON Syntax Reference

JSON (JavaScript Object Notation) is a strict, minimal data format — far stricter than the JavaScript object literals it resembles. This sheet covers the full grammar, the escape sequences, and the exact ways JSON5/JSONC relax the rules, since "my JSON won't parse" is almost always one of these differences.

Quick reference

Data types

Type Example Notes
String `"hello"` Double quotes only, never single quotes
Number `42`, `-3.14`, `1.5e10` No leading zeros (`01` is invalid), no `NaN`/`Infinity`
Boolean `true`, `false` Lowercase, unquoted
Null `null` Lowercase, unquoted
Object `{"key": "value"}` Keys must be double-quoted strings
Array `[1, 2, 3]` Mixed types allowed

Escape sequences (inside strings)

Escape Meaning
`\"` Double quote
`\\` Backslash
`\/` Forward slash (optional — `/` is valid unescaped too)
`\n` Newline
`\t` Tab
`\r` Carriage return
`\b` Backspace
`\f` Form feed
`\uXXXX` Unicode code point (4 hex digits)

JSON vs JSON5 vs JSONC

Feature JSON JSON5 JSONC
Trailing commas No Yes No
Comments (`//`, `/* */`) No Yes Yes
Unquoted object keys No Yes (if valid identifier) No
Single-quoted strings No Yes No
Multi-line strings (`\` continuation) No Yes No
Leading `+` on numbers No Yes No
Hex numbers (`0xFF`) No Yes No

JSONC (used by tsconfig.json, VS Code settings) is plain JSON plus comments — nothing else. JSON5 is a much larger superset aimed at hand-written config files, not data interchange; don't feed JSON5 to a strict JSON.parse().

Common patterns

Parsing safely

try {
  const data = JSON.parse(rawInput);
} catch (e) {
  console.error('Invalid JSON:', e.message);
}

Every JSON.parse() on untrusted or user-supplied input belongs in a try/catch — a malformed payload throws a SyntaxError, it doesn't return null.

Pretty-printing

JSON.stringify(data, null, 2);   // 2-space indent
JSON.stringify(data, null, '\t'); // tab indent

Filtering keys while stringifying

JSON.stringify({ id: 1, password: 'secret', name: 'x' }, ['id', 'name']);
// -> {"id":1,"name":"x"}

The second argument can be an array of allow-listed keys instead of a replacer function.

Deep-cloning a JSON-safe object

const clone = JSON.parse(JSON.stringify(original));

Fast and dependency-free, but it has real gaps: undefined and functions are dropped entirely, Date objects become ISO strings, Map/Set serialize as an empty {} (silently losing every entry, not dropped as a key), and circular references throw a TypeError instead of cloning.

Reviving dates on parse

JSON.parse(raw, (key, value) => {
  if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T/.test(value)) {
    return new Date(value);
  }
  return value;
});

Pitfalls

  • Trailing commas break strict JSON: {"a": 1,} throws Unexpected token } in JSON.parse. This is the single most common "my config file won't load" bug when copy-pasting from JS source into a .json file.
  • undefined, NaN, Infinity, and functions vanish silently on stringify: JSON.stringify({a: undefined, b: NaN}) produces {"b":null} — no error, just data loss. Check for these before you serialize if their absence would be a bug.
  • Comments are not valid JSON, full stop: // notes or / block / anywhere in a .json file fails to parse. If you need comments, either use JSONC-aware tooling explicitly or a JSON5 parser — never assume JSON.parse will skip them.
  • Duplicate keys are legal grammar but implementation-defined: {"a":1,"a":2} parses without error in most engines, silently keeping the last value. Don't rely on this — it's not guaranteed by the JSON spec (RFC 8259) which just says behavior is undefined.
  • Numbers lose precision above 2^53: JSON has no distinct integer type, and JS Number is a 64-bit float, so a 19-digit ID like a Snowflake or bigint from another language can silently round. Send large IDs as strings, or parse with a bigint-aware library.

Related ZipKit tools

Related cheatsheets

  • Regex Cheatsheet — the pattern syntax behind JSON Schema's pattern keyword and most JSON validators.
  • URL Encoding Reference — the other data-safety encoding JSON payloads often need alongside percent-encoded query params.