What Is JSON?
JSON (JavaScript Object Notation) is the most widely used data interchange format on the web. Every REST API, configuration file and NoSQL database you work with probably uses JSON. Despite its simplicity, poorly formatted JSON is one of the most common sources of bugs in web development — a missing comma or misplaced bracket can bring an entire application to its knees.
Douglas Crockford formalised the JSON specification in the early 2000s, drawing on the object literal syntax already present in JavaScript. The format caught on because it solved a real problem: XML was verbose and painful to parse, while binary formats were not human-readable. JSON offered a middle ground — lightweight enough for machines to process efficiently, readable enough for developers to debug by eye.
JSON supports six data types: strings (in double quotes), numbers, booleans (true/false), null, arrays (ordered lists in square brackets) and objects (key-value pairs in curly braces). That is the entire specification. No comments, no trailing commas, no single quotes, no undefined. This constraint is a feature — it means every JSON parser on every platform produces identical results.
JSON Syntax Rules
Getting these right eliminates 90% of JSON errors:
- Keys must be double-quoted strings —
"name"notnameor'name' - String values use double quotes only —
"hello"not'hello' - No trailing commas — the last item in an array or object must not have a comma after it
- No comments — JSON does not support
//or/* */comments - Numbers have no leading zeros —
0.5is valid,05is not - No NaN or Infinity — these JavaScript values are not valid JSON numbers
- Strings must escape control characters — newlines become
\n, tabs become\t, backslashes become\\
One subtlety that catches people: JSON technically allows duplicate keys in objects. The specification says behaviour is undefined when duplicates exist, but most parsers silently use the last value. Do not rely on this — it is a source of hard-to-trace bugs when APIs silently overwrite fields.
Common JSON Errors and How to Fix Them
After formatting thousands of JSON documents, these are the errors developers hit most often, roughly in order of frequency.
Trailing Comma
By far the most common mistake. JavaScript, TypeScript and Python all allow trailing commas in their own object and dictionary syntax, so developers habitually include them. JSON does not forgive this.
// Invalid — trailing comma after "age"
{"name": "Alice", "age": 30,}
// Valid
{"name": "Alice", "age": 30}
This is especially insidious in arrays built by concatenation or code generation, where the trailing comma is added by a loop that does not special-case the last element.
Single Quotes
JSON strictly requires double quotes. If you are copying from Python repr() output, JavaScript console logs, or YAML, watch for single quotes sneaking in.
// Invalid — single quotes
{'name': 'Alice'}
// Valid
{"name": "Alice"}
Unescaped Special Characters
Backslashes, newlines and tabs inside strings must be escaped. This hits Windows developers hardest because file paths use backslashes.
// Invalid — unescaped backslash
{"path": "C:\Users\alice\Documents"}
// Valid
{"path": "C:\\Users\\alice\\Documents"}
Multiline strings are another trap. If you have copied a paragraph of text into a JSON value, every literal newline must be replaced with \n. JSON strings cannot span multiple lines.
Unexpected Token Errors
When a JSON parser reports "unexpected token", it usually means the structure is broken at a deeper level — a missing closing bracket, a value where a key was expected, or a stray character from copy-pasting. The error position the parser reports is where it gave up, not necessarily where the actual mistake is. Work backwards from that position to find the real problem.
Format & Validate Your JSON Instantly
Paste your JSON and get instant formatting, validation and error detection — all in your browser, nothing uploaded.
Open JSON Formatter →Pretty-Printing vs Minification
Pretty-printing adds indentation and line breaks to make JSON human-readable. Use 2-space or 4-space indentation — the choice is purely a team convention, though 2-space is more common in JavaScript ecosystems and 4-space in Python projects. Pretty-printed JSON is essential for config files, documentation, debugging, and any situation where a human needs to read or edit the data.
Minification strips all unnecessary whitespace — spaces after colons, spaces after commas, indentation and line breaks. A typical JSON API response can be 30-40% smaller when minified, which translates directly to faster network transfers and lower bandwidth costs. Always minify JSON in production API responses and stored data where readability is not needed.
In practice, you will constantly switch between the two. Minified JSON comes back from an API, you pretty-print it for debugging, make changes, then minify before sending it back. Having a formatter that does both operations with a single click saves cumulative hours over a project lifetime.
Working with Nested JSON
Real-world JSON is usually deeply nested. Here is a practical example of a well-structured API response showing a user with an address and order history:
{
"user": {
"id": 12345,
"name": "Alice Smith",
"email": "alice@example.com",
"address": {
"street": "123 High Street",
"city": "London",
"postcode": "SW1A 1AA"
},
"orders": [
{"id": "ORD-001", "total": 49.99, "status": "delivered"},
{"id": "ORD-002", "total": 125.00, "status": "processing"}
]
}
}
When debugging nested JSON, a formatter with depth indicators and collapsible sections saves enormous time. Without one, you are counting brackets and mentally tracking indentation levels across hundreds of lines. Our JSON formatter shows the nesting depth, key count, and data type at a glance.
JSON Path Queries: Navigating Complex Data
JSONPath is a query language for extracting data from JSON documents, similar to XPath for XML. When you are working with a large API response and need to find specific values buried several levels deep, JSONPath expressions let you pinpoint exactly what you need.
Common JSONPath expressions:
$.user.name— access a specific nested field$.user.orders[0]— access the first element of an array$.user.orders[*].total— get all total values from every order$.user.orders[?(@.status=="delivered")]— filter orders by status
Most languages have JSONPath libraries: jsonpath-ng in Python, jsonpath-plus in JavaScript, and JsonPath.Net in C#. Learning JSONPath pays dividends whenever you are processing webhook payloads, testing APIs, or writing data transformation pipelines.
JSON on the Command Line: jq
If you work with JSON regularly, jq is indispensable. It is a command-line JSON processor that can pretty-print, filter, transform and query JSON data. Here are the patterns you will use daily:
# Pretty-print a JSON file
cat data.json | jq .
# Extract a specific field
cat data.json | jq '.user.name'
# Get all order totals
cat data.json | jq '.user.orders[].total'
# Filter and transform
cat data.json | jq '.user.orders[] | select(.status == "delivered") | .total'
# Pipe API response directly
curl -s https://api.example.com/users/1 | jq '.data.email'
The jq syntax feels unusual at first, but once it clicks, you will find yourself reaching for it constantly. It is especially powerful when combined with shell pipes — you can chain API calls, extract data, transform formats and produce reports without writing a single line of application code.
JSON vs Other Formats
Understanding when JSON is the right choice and when alternatives serve better helps you make better architectural decisions.
JSON vs XML: JSON is more compact and easier to parse. XML offers attributes, namespaces and built-in schema validation, which matters in enterprise integrations and document markup. If you are building a REST API, JSON is the default choice. If you are working with SOAP services, document standards like SVG or XHTML, or systems that need inline metadata, XML still has a role.
JSON vs YAML: YAML is a superset of JSON that adds comments, multiline strings, anchors and aliases. YAML is generally preferred for configuration files that humans edit — Kubernetes manifests, CI/CD pipelines, Ansible playbooks. JSON is preferred for data interchange where machines are the primary audience. One gotcha: YAML implicit typing can cause surprises — on becomes a boolean, 3.14 becomes a float, and NO becomes false.
JSON vs Protocol Buffers / MessagePack: Binary formats are significantly smaller and faster to parse. A typical JSON payload shrinks 50-70% with Protocol Buffers. The trade-off is human readability — you cannot open a protobuf message in a text editor. Use binary formats for high-throughput microservice communication; use JSON for public APIs and anything that needs debugging.
JSON in Different Languages
| Language | Parse | Stringify |
|---|---|---|
| JavaScript | JSON.parse(str) | JSON.stringify(obj, null, 2) |
| Python | json.loads(str) | json.dumps(obj, indent=2) |
| C# | JsonSerializer.Deserialize<T>(str) | JsonSerializer.Serialize(obj) |
| Java | new ObjectMapper().readTree(str) | mapper.writerWithDefaultPrettyPrinter() |
| PHP | json_decode($str) | json_encode($obj, JSON_PRETTY_PRINT) |
| Go | json.Unmarshal([]byte(str), &v) | json.MarshalIndent(v, "", " ") |
| Ruby | JSON.parse(str) | JSON.pretty_generate(obj) |
| Rust | serde_json::from_str(str) | serde_json::to_string_pretty(&v) |
A common pitfall across languages: large integers. JSON numbers have no defined precision, but JavaScript and therefore most JSON parsers use IEEE 754 double-precision floats, which can only represent integers exactly up to 2^53. If your API returns 64-bit integer IDs, they can lose precision when parsed in JavaScript. The standard workaround is to send large IDs as strings.
JSON Schema: Validating Structure
JSON Schema is a vocabulary that lets you annotate and validate JSON documents. Think of it as TypeScript types for JSON — you define the expected shape, types, and constraints, then validate incoming data against that 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, "maximum": 150}
}
}
JSON Schema is particularly valuable in API development. Use it to validate request bodies before processing, generate API documentation automatically, and create test fixtures. Most API frameworks including FastAPI, NestJS and Spring Boot can generate JSON Schema from your type definitions.
Security Considerations
JSON itself is inert data, but how you handle it can introduce vulnerabilities. Be aware of these risks:
JSON injection: If you build JSON strings through concatenation rather than using a proper serialiser, user input can break out of string boundaries and inject additional key-value pairs. Always use your language built-in JSON serialiser.
Prototype pollution: In JavaScript, parsing JSON with keys like __proto__ or constructor can modify the prototype chain of objects, potentially leading to security vulnerabilities. Use Object.create(null) for untrusted data or validate keys before processing.
Denial of service: Deeply nested JSON — thousands of levels — can cause stack overflows in recursive parsers. Extremely large JSON payloads can exhaust memory. Set maximum payload size limits and consider streaming parsers for large datasets.
JSON Best Practices
- Use consistent naming conventions —
camelCaseis most common in JavaScript APIs,snake_casein Python APIs. Pick one and stick with it across your entire API surface. - Keep nesting shallow — more than 3-4 levels deep often signals a design problem. Consider flattening or normalising your data structure.
- Use arrays for ordered collections, objects for named properties — do not use objects with numeric keys as substitutes for arrays.
- Validate on both ends — validate JSON structure when sending and receiving, not just one side.
- Handle missing fields gracefully — do not assume every optional field will be present. Use optional chaining or equivalent patterns in your language.
- Date handling — JSON has no native date type. Use ISO 8601 strings consistently. Never use Unix timestamps as numbers unless your entire system agrees on seconds vs milliseconds.
- Null vs absent — decide whether missing fields mean unknown or not applicable and be consistent throughout your API.
Try the JSON Formatter
Format, minify and validate JSON with syntax highlighting and error detection. Everything runs in your browser — your data never leaves your device.
Open JSON Formatter →