How to Format JSON: A Complete Guide for Developers

· 15 min read

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:

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:

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

LanguageParseStringify
JavaScriptJSON.parse(str)JSON.stringify(obj, null, 2)
Pythonjson.loads(str)json.dumps(obj, indent=2)
C#JsonSerializer.Deserialize<T>(str)JsonSerializer.Serialize(obj)
Javanew ObjectMapper().readTree(str)mapper.writerWithDefaultPrettyPrinter()
PHPjson_decode($str)json_encode($obj, JSON_PRETTY_PRINT)
Gojson.Unmarshal([]byte(str), &v)json.MarshalIndent(v, "", " ")
RubyJSON.parse(str)JSON.pretty_generate(obj)
Rustserde_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

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 →
Need a developer? Hire Anthony D Johnson — Senior .NET & Azure Developer →