JSON (JavaScript Object Notation) is the standard data exchange format for web APIs, configuration files, and application data. Despite its simplicity, JSON has strict syntax rules that trip up developers, and common formatting choices affect readability, debuggability, and compatibility. This guide covers the rules, the conventions, and the edge cases worth knowing.
JSON Syntax Rules
JSON is a strict subset of JavaScript object notation, but with important differences. Strings must use double quotes — not single quotes. Object keys must be strings, also in double quotes. Trailing commas after the last item in an object or array are not allowed. Comments are not allowed. These rules catch most developers who are used to JavaScript's more lenient syntax.
- Strings: double quotes only. 'hello' is invalid; "hello" is correct.
- Keys: must be strings in double quotes. {name: "Alice"} is invalid; {"name": "Alice"} is correct.
- No trailing commas: [1, 2, 3,] is invalid.
- No comments: // and /* */ are not supported.
- Numbers: no leading zeros (01 is invalid), no NaN, no Infinity.
- Values: string, number, object, array, true, false, or null — nothing else.
Pretty-Print vs. Minified
Pretty-printed JSON has consistent indentation (typically 2 or 4 spaces) and each key-value pair on its own line. It is easy to read and diff, which makes it the right choice for configuration files that humans edit, API responses in development, and documentation examples. Minified JSON removes all non-essential whitespace, reducing file size at the cost of human readability.
For production API responses, minified JSON reduces bytes transferred. However, if HTTP compression (gzip or Brotli) is enabled — which it should be — the difference in compressed size is minimal, because the compressor handles redundant whitespace efficiently. In practice, always serve compressed responses and do not worry about JSON minification for API responses. Reserve minification for tokens, cookies, and contexts where compression is not available.
Key Naming Conventions
JSON itself has no opinion on key naming. In practice, the convention follows the language of the API consumer. JavaScript and Node.js APIs typically use camelCase (firstName, userId). Python and Ruby APIs often use snake_case (first_name, user_id). Public APIs should document their convention and apply it consistently — mixing both in the same API is a source of constant friction.
Keep key names concise but descriptive. Abbreviations save a few bytes but hurt readability; with compression, the transfer savings are negligible. Avoid names that conflict with JavaScript reserved words if the API will be consumed in JavaScript, and avoid starting names with numbers or including spaces, which require unusual handling in every consumer.
Common Type Pitfalls
JSON has no date type. Dates are typically serialized as ISO 8601 strings ("2025-11-12T00:00:00Z") or as Unix timestamps (numbers). Pick one convention and document it. Parsing ISO strings to Date objects works reliably; parsing Unix timestamps requires knowing whether they are in seconds or milliseconds.
JSON also has no distinction between integers and floats — they are all numbers. Very large integers (above 2^53 - 1) lose precision when parsed by JavaScript's JSON.parse(), because they are stored as IEEE 754 doubles. APIs that deal with large identifiers (such as Twitter/X's tweet IDs) often serialize them as strings to avoid this problem.
When to Use JSON5 or JSONC
JSON5 is a superset of JSON that adds trailing commas, single-quoted strings, comments, and unquoted keys. JSONC (JSON with Comments) adds only comments. Both are useful for configuration files that humans edit — tsconfig.json, VS Code settings, and many other developer tools use JSONC. They are not appropriate for API responses, which must be consumed by standard JSON parsers.