DEV Community

David
David

Posted on

JSON Formatting 101: Pretty Print, Validate, and Debug Like a Pro

You just hit an API endpoint and got back a wall of minified JSON. It's 2,000 characters of brackets, colons, and quotes with zero whitespace. Good luck finding that nested address.city field.

Sound familiar? JSON formatting is one of those micro-tasks developers do dozens of times a day but rarely think about. Let's break down what's actually happening when you "pretty print" JSON — and how to do it faster.

What Is JSON Formatting?

JSON formatting (or "pretty printing") transforms compact JSON into human-readable, indented output.

Before (minified):

{"users":[{"name":"Alice","age":30,"roles":["admin","editor"]},{"name":"Bob","age":25,"roles":["viewer"]}]}
Enter fullscreen mode Exit fullscreen mode

After (formatted):

{
  "users": [
    {
      "name": "Alice",
      "age": 30,
      "roles": [
        "admin",
        "editor"
      ]
    },
    {
      "name": "Bob",
      "age": 25,
      "roles": [
        "viewer"
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Same data. Radically different readability.

Why Minified JSON Exists

APIs send minified JSON because whitespace costs bytes:

Format Size Savings
Pretty printed 258 bytes
Minified 105 bytes 59% smaller

Over millions of API responses, that whitespace adds up. Content-Encoding (gzip/brotli) helps, but starting smaller is still better for bandwidth, parsing speed, and storage.

The JSON.stringify() Power Move

In JavaScript, formatting JSON is a one-liner most devs underuse:

// Basic pretty print with 2-space indent
const formatted = JSON.stringify(data, null, 2);

// Tab indent
const tabbed = JSON.stringify(data, null, '\t');

// With a replacer — filter specific keys
const filtered = JSON.stringify(data, ['name', 'email'], 2);
Enter fullscreen mode Exit fullscreen mode

That second argument (the replacer) is surprisingly powerful:

// Custom replacer function
const sanitized = JSON.stringify(data, (key, value) => {
  if (key === 'password' || key === 'token') return '[REDACTED]';
  return value;
}, 2);
Enter fullscreen mode Exit fullscreen mode

Now you can format AND sanitize in one step — great for logging.

Validating JSON: The Common Pitfalls

Formatting only works if your JSON is valid. Here are the mistakes that trip people up:

1. Trailing Commas

//  Invalid
{
  "name": "Alice",
  "age": 30,
}

//  Valid
{
  "name": "Alice",
  "age": 30
}
Enter fullscreen mode Exit fullscreen mode

2. Single Quotes

//  Invalid  JSON requires double quotes
{ 'name': 'Alice' }

//  Valid
{ "name": "Alice" }
Enter fullscreen mode Exit fullscreen mode

3. Unquoted Keys

//  Invalid  this is JavaScript, not JSON
{ name: "Alice" }

//  Valid
{ "name": "Alice" }
Enter fullscreen mode Exit fullscreen mode

4. Comments

//  Invalid  JSON has no comments
{
  // This breaks everything
  "name": "Alice"
}
Enter fullscreen mode Exit fullscreen mode

If you've ever pasted a config and gotten Unexpected token, one of these is usually the culprit.

Formatting in Different Languages

Python

import json

data = {"name": "Alice", "scores": [95, 87, 92]}

# Pretty print
print(json.dumps(data, indent=2))

# Sort keys (great for diffs)
print(json.dumps(data, indent=2, sort_keys=True))
Enter fullscreen mode Exit fullscreen mode

CLI (jq)

# Format a file
cat data.json | jq '.'

# Format API response inline
curl -s https://api.example.com/users | jq '.'

# Extract + format specific fields
curl -s https://api.example.com/users | jq '.[] | {name, email}'
Enter fullscreen mode Exit fullscreen mode

PHP

echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
Enter fullscreen mode Exit fullscreen mode

Go

formatted, _ := json.MarshalIndent(data, "", "  ")
fmt.Println(string(formatted))
Enter fullscreen mode Exit fullscreen mode

When Formatting Actually Matters

Beyond "making it readable," there are real use cases where formatting is essential:

1. Debugging API responses — When something breaks and you need to trace the data shape quickly.

2. Config filespackage.json, tsconfig.json, .eslintrc — these should always be readable.

3. Git diffs — Minified JSON creates single-line diffs that are impossible to review. Format before committing.

4. Documentation — Showing example payloads? Format them. Your future self (and teammates) will thank you.

5. Logging — Structured logs with pretty-printed JSON are night and day for debugging in production.

The Quick Way: Browser-Based Formatting

When you just need to paste some JSON and see it formatted — no install, no IDE, no terminal — a browser tool is the fastest path.

I built jsonformat.co for exactly this. Paste your JSON, get it formatted instantly. It also validates, highlights errors, and handles large payloads — all client-side, nothing sent to a server.

No signup, no ads in your face. Just paste → format → copy. The way dev tools should work.

Pro Tips

  1. Use jq for piping — If you work with APIs in the terminal, jq is indispensable.
  2. Sort keys before comparingJSON.stringify(a, null, 2) vs JSON.stringify(b, null, 2) won't catch reordered keys. Use sort_keys or the replacer.
  3. Watch your depth — Deeply nested JSON (10+ levels) is usually a data modeling problem, not a formatting one.
  4. Set your editor default — VS Code: "editor.defaultFormatter" for JSON files. Auto-format on save.
  5. Validate before you parse — Don't try { JSON.parse(x) } in production without proper error handling. Malformed JSON from external sources is more common than you'd think.

JSON formatting is one of those "boring but essential" developer skills. You don't think about it until you're staring at a 500-line minified response at 2 AM trying to find a typo.

Keep a good formatter bookmarked. Your eyes will thank you. 👀


This is part of the Developer Tools Deep Dives series, where I break down the tools and concepts developers use daily. Check out the rest of the series for more.

Top comments (0)