JSON (JavaScript Object Notation) is the lingua franca of the web. It connects APIs, configures applications, stores structured data, and powers modern front-end and back-end systems alike. Yet for all its ubiquity, developers — from beginners to seniors — frequently run into JSON errors, formatting inconsistencies, and validation failures.
This guide covers everything: the syntax rules, all six data types, correct formatting conventions, the most common errors and how to fix them, and best practices for using JSON in production systems in 2026.
What Is JSON?
JSON is a lightweight, text-based data-interchange format originally derived from JavaScript object literal syntax. Despite the name, JSON is entirely language-independent — there are JSON parsers for every major programming language, runtime, and platform.
Douglas Crockford popularized the format in the early 2000s. It was standardised in ECMA-404 (2013) and RFC 8259 (2017), which is the definitive specification today.
JSON is a serialisation format, not a programming language. It describes static data structures — there are no functions, no comments, no executable expressions.
Why JSON replaced XML
Before JSON, XML dominated web data exchange. JSON displaced it for three reasons:
- Conciseness — JSON removes tag verbosity. The same data typically occupies 30–50% less space.
- Native parsing —
JSON.parse()is built into every modern JavaScript runtime, browser, and Node.js. No library required. - Readability — Humans can read and write JSON without tooling; XML requires discipline to stay readable.
The Six JSON Data Types
JSON supports exactly six value types. Understanding what is and isn't valid is the foundation of working with JSON correctly.
| Type | Syntax | Example | Notes |
|---|---|---|---|
| String | Double-quoted Unicode text | "Hello, world" | Must use ", not ' |
| Number | Integer or decimal | 42, 3.14, -7, 1.5e10 | No hex, no NaN, no Infinity |
| Boolean | Lowercase literal | true / false | Not True or TRUE |
| Null | Lowercase literal | null | Not None, nil, or NULL |
| Array | Ordered list in [] | [1, "two", true] | Mixed types allowed |
| Object | Key-value pairs in {} | {"key": "value"} | Keys must be strings |
Object Syntax
A JSON object is a collection of zero or more key-value pairs wrapped in curly braces. Keys must be strings (double-quoted). Values can be any of the six types. Pairs are separated by commas; there is no trailing comma after the last pair.
{ "name": "Jane Smith", "age": 32, "active": true, "score": 9.8, "department": null, "roles": ["admin", "editor"] }
Nested objects
Objects can be nested to any depth. There is no theoretical nesting limit, though parsers may enforce practical maximums (typically 500–1000 levels).
{ "user": { "id": 1001, "address": { "city": "Berlin", "country": "DE" } } }
Array Syntax
A JSON array is an ordered list of values in square brackets. Items can be of different types. Like objects, arrays do not allow trailing commas.
[ { "id": 1, "name": "Alice" }, { "id": 2, "name": "Bob" }, { "id": 3, "name": "Carol" } ]
String Rules and Escape Sequences
JSON strings are sequences of Unicode characters enclosed in double quotes. Certain characters must be escaped with a backslash:
| Escape | Meaning | Example |
|---|---|---|
\" | Double quote | "She said \"hello\"" |
\\ | Backslash | "C:\\Users\\name" |
\/ | Forward slash (optional) | "https:\/\/example.com" |
\n | Newline | "line1\nline2" |
\r | Carriage return | "CR\r" |
\t | Tab | "col1\tcol2" |
\uXXXX | Unicode code point | "A" = "A" |
Literal newlines and tabs inside a string are not valid. You must use \n and \t escape sequences instead. Many hand-written config errors come from pasting multi-line text directly into a string value.
Number Format
JSON numbers follow a strict subset of JavaScript number syntax. The following are valid JSON numbers:
42 // integer -7 // negative 3.14159 // decimal 0.001 // less than 1 — note leading 0 1.5e10 // scientific notation -2.7E-4 // negative scientific
The following are not valid JSON numbers: 0xFF (hex), NaN, Infinity, -Infinity, 077 (octal), +42 (explicit positive sign).
The 7 Most Common JSON Errors
These are the errors that break JSON validation most often in the real world:
{ "a": 1, "b": 2, ← invalid }
{ "a": 1, "b": 2 }
{ 'name': 'Alice' }
{ "name": "Alice" }
{ name: "Alice" }
{ // user data "name": "Alice" }
| Error | Cause | Fix |
|---|---|---|
| Trailing comma | Comma after last property or element | Remove the final comma |
| Single quotes | Using ' instead of " | Replace all single quotes |
| Unquoted keys | JavaScript object syntax habit | Add double quotes around every key |
| Comments | // or /* */ copied from JS/config | Remove all comments |
| Undefined value | undefined is not a JSON type | Replace with null or omit the key |
| NaN / Infinity | Not valid JSON numbers | Use a numeric sentinel or null |
| Duplicate keys | Repeated keys in one object | Parsers accept it but behavior is undefined — deduplicate |
The first three errors (trailing commas, single quotes, unquoted keys) are automatically fixed by the Auto-Repair button in our JSON Formatter.
Formatting JSON: Beautify vs Minify
Formatted (beautified) JSON uses consistent indentation and line breaks. Minified JSON removes all whitespace. Both are semantically equivalent — parsers see the same data.
{ "status": "ok", "data": { "id": 42, "active": true } }
{"status":"ok","data":{"id":42,"active":true}}
Indentation conventions
| Convention | Usage | Size overhead |
|---|---|---|
| 2 spaces | Node.js, npm, most JS style guides | Low |
| 4 spaces | Python projects, many back-end teams | Medium |
Tab (\t) | Editor-agnostic, user-controlled width | Lowest character count |
| No indent (minified) | Production APIs, embedded configs | None |
For files in version control, pick the indentation your project already uses and stick to it. Changing indentation between commits creates noisy diffs that obscure real changes.
Using JSON in JavaScript
JavaScript has two native methods for working with JSON:
const str = '{"name":"Alice","age":30}'; const obj = JSON.parse(str); console.log(obj.name); // "Alice"
const obj = { name: "Alice", age: 30 }; // Minified JSON.stringify(obj); // → '{"name":"Alice","age":30}' // Formatted with 2-space indent JSON.stringify(obj, null, 2); // Filter/transform with replacer JSON.stringify(obj, ['name']); // only 'name' key
Handling parse errors
function safeParseJSON(str) { try { return { ok: true, data: JSON.parse(str) }; } catch (err) { return { ok: false, error: err.message }; } }
The reviver parameter
JSON.parse accepts an optional reviver function that transforms values during parsing. A common use-case is converting ISO 8601 date strings back to Date objects:
const ISO = /^\d{4}-\d{2}-\d{2}T/;
const data = JSON.parse(str, (key, value) =>
typeof value === 'string' && ISO.test(value)
? new Date(value)
: value
);Using JSON in Python
import json # Parse (deserialise) data = json.loads('{"name": "Alice", "age": 30}') print(data['name']) # Alice # Serialise json.dumps(data) # minified json.dumps(data, indent=2) # formatted # Read/write file with open('data.json', 'r') as f: obj = json.load(f) with open('out.json', 'w') as f: json.dump(obj, f, indent=2)
Python maps JSON types as: object → dict, array → list, string → str, number → int or float, boolean → bool, null → None. When serialising, Python's True/False/None are automatically converted to JSON's true/false/null.
JSON in REST APIs
REST APIs return JSON for data responses. The standard conventions are:
// Request POST /api/users HTTP/1.1 Content-Type: application/json { "name": "Alice", "email": "alice@example.com" } // Response HTTP/1.1 201 Created Content-Type: application/json { "id": 1001, "name": "Alice", "created_at": "2026-06-06T12:00:00Z" }
Common API JSON patterns
| Pattern | Description | Example |
|---|---|---|
| Envelope | Wrap data in a data key | {"data": {...}, "meta": {...}} |
| Error object | Consistent error shape | {"error": {"code": 404, "message": "Not found"}} |
| Pagination | Next/prev links + count | {"items": [...], "total": 100, "next": "/api?page=2"} |
| Timestamps | ISO 8601 strings | "2026-06-06T12:00:00Z" |
| IDs as strings | Avoid 64-bit integer loss | "id": "9007199254740993" instead of large integer |
JavaScript's Number type is a 64-bit float and can only safely represent integers up to 2⁵³ − 1 (9,007,199,254,740,991). If your IDs exceed this, serialize them as strings in JSON to avoid silent precision loss in browser clients.
JSON5 and JSONC (Extensions)
Two unofficial extensions address JSON's limitations for human-authored config files:
JSON5
JSON5 adds comments, trailing commas, single-quoted strings, unquoted keys, multi-line strings, and hex numbers. It is widely used for config files in tools like Babel, ESLint (via .eslintrc), and TypeScript (tsconfig.json accepts some JSON5 features).
JSONC (JSON with Comments)
JSONC is JSON plus // and /* */ comments only. Used by VS Code settings files (settings.json, launch.json). It is not valid JSON and requires a JSONC-aware parser.
Neither JSON5 nor JSONC is accepted by standard JSON.parse(). If you receive one of these as a string, you need a dedicated parser library. For API payloads, always use strict JSON.
JSON Schema Validation
JSON Schema is a vocabulary for describing the structure of JSON data. You define a schema document (itself written in JSON) that specifies required fields, types, string patterns, numeric ranges, and more. Validators then check any JSON document against the schema.
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "required": ["name", "email"], "properties": { "name": { "type": "string", "minLength": 1 }, "email": { "type": "string", "format": "email" }, "age": { "type": "integer", "minimum": 0 } } }
JSON Schema is used extensively in: OpenAPI/Swagger API specifications, VS Code IntelliSense for config files, form validation in front-end frameworks, and automated API contract testing.
Best Practices for JSON in 2026
- Always validate on both ends. Don't trust JSON from external sources. Validate structure and types with JSON Schema or manual checks before using the data.
- Use ISO 8601 for dates.
"2026-06-06T12:00:00Z"is unambiguous. Never embed locale-specific date strings in JSON. - Strings for large IDs. Any ID that could exceed 2⁵³ should be a string in the JSON payload to prevent silent precision loss in JavaScript clients.
- Consistent key naming. Pick one convention —
camelCase,snake_case, orkebab-case— and use it throughout your entire API. Mixing is a maintenance problem. - Minify for network, format for humans. Ship minified JSON in API responses. Store formatted JSON in version control for config files and schemas humans need to read.
- Avoid deeply nested structures. Flat or shallow structures (2–3 levels) are easier to work with in code. Very deep nesting often signals a missing abstraction.
- Explicit nulls vs missing keys. Decide whether missing key means "not provided" and explicit
nullmeans "intentionally empty." Document and enforce this distinction consistently in your API.
Formatting JSON on the Command Line
jq is the standard command-line JSON processor. Install it with your package manager.
# Pretty-print cat data.json | jq . # Minify jq -c . data.json # Extract a value jq '.user.name' data.json # Filter array by condition jq '.users[] | select(.active == true)' data.json # Output specific keys jq '.users[] | {id, name}' data.json # Sort keys jq --sort-keys . data.json # Pretty-print API response inline curl -s https://api.example.com/data | jq .
For quick formatting without installing anything, our JSON Formatter runs entirely in the browser. Upload a file, paste a payload, or use it for live diff comparison — no account required.
JSON vs Alternatives in 2026
| Format | Best for | Weakness |
|---|---|---|
| JSON | APIs, config, storage — universal support | No comments, strict syntax |
| YAML | Human-authored config (Docker, Kubernetes, GitHub Actions) | Indentation-sensitive, surprising type coercions |
| TOML | Config files — very readable for flat structures | Awkward for deeply nested data |
| Protocol Buffers | High-performance, typed, binary inter-service communication | Binary (not human-readable), requires schema |
| MessagePack | Binary JSON — same structure, smaller size | Not human-readable |
| XML | Document-centric data, SOAP APIs, SVG | Verbose, complex parsing |
For most web APIs in 2026, JSON remains the default choice. Its universality, developer familiarity, and native browser/runtime support make it the lowest-friction option. Only switch to binary formats when measured performance requirements justify the added complexity.