What is JSON and how to format it correctly
A practical guide to JSON syntax, the mistakes that break it, and how a formatter turns a wall of text into something you can actually debug.
On this page
- Where JSON came from
- The basic building blocks
- Every value type at a glance
- The rules that trip people up
- Decoding common parser errors
- Numbers, precision, and other quiet gotchas
- Why formatting matters more than it seems
- Try it yourself
- Working with JSON in JavaScript
- JSON in the wild
- From raw JSON to working code
- When JSON is the wrong tool
- A few debugging habits worth adopting
- Frequently asked questions
If you've worked with an API, a config file, or a browser's network tab, you've run into JSON. It's the format most web services use to send data back and forth, and it's popular for a simple reason: it's small, it's readable by both humans and machines, and almost every programming language can parse it without extra libraries.
But "readable" only holds up when the JSON is formatted. A 200KB API response returned as one unbroken line of text is technically valid JSON — and completely useless to look at. That's the gap a formatter fills.
Where JSON came from
JSON stands for JavaScript Object Notation, and it was popularised in the early 2000s by Douglas Crockford, who famously said he didn't invent it so much as discover it — the syntax already existed inside JavaScript. At the time, the dominant data format for web services was XML, which wrapped every value in opening and closing tags and needed dedicated parsers to read. JSON expressed the same data in a fraction of the bytes, mapped directly onto the data structures most languages already had (objects, arrays, strings, numbers), and could be parsed natively in the browser. The result: as browser-based apps took over, JSON quietly became the default language of APIs, and today formats like configuration files, log streams, and even database documents speak it.
The basic building blocks
JSON has exactly two container types, and everything is built from them:
- Objects — unordered collections of key/value pairs, wrapped in curly braces:
{"name": "Alex", "active": true} - Arrays — ordered lists of values, wrapped in square brackets:
["red", "green", "blue"]
Values inside either one can be a string, a number, a boolean, null, or another object or array — which is how you get deeply nested structures like a list of users, each with their own address object, each containing its own fields:
{
"users": [
{
"name": "Alex",
"active": true,
"address": {
"city": "Kochi",
"pincode": "682001"
},
"roles": ["editor", "admin"]
}
],
"total": 1
}That's the entire compositional model. Every JSON document you'll ever meet — a 50MB API dump or a three-line config — is just these pieces nested inside each other.
Every value type at a glance
| Type | Example | Notes |
|---|---|---|
| String | "hello" | Double quotes only; supports \n, \", \\ and \uXXXX escapes |
| Number | 42, -3.14, 2.5e10 | No leading zeros, no trailing dot, no NaN or Infinity |
| Boolean | true, false | Lowercase only |
| Null | null | The only "empty" value; undefined does not exist in JSON |
| Object | {"key": "value"} | Keys must be double-quoted strings |
| Array | [1, "two", null] | Values can be of mixed types |
The rules that trip people up
JSON looks like a JavaScript object literal, which is exactly why people assume JavaScript's more relaxed rules apply. They don't. JSON has a stricter, fixed grammar:
- Keys must be strings, and they must use double quotes.
{"name": "Alex"}is valid;{name: "Alex"}is not, and neither is{'name': 'Alex'}. - Single quotes are never allowed, for keys or values.
- No trailing commas.
["a", "b",]fails to parse — that dangling comma after the last item is a syntax error, even though it's harmless in JavaScript arrays. - No comments. Not // and not /* */. The JSON spec deliberately leaves comments out, which is why config formats like JSON5 or YAML exist for cases where you actually want to annotate your data.
- Numbers can't have leading zeros or a trailing decimal point — 01 and 5. are both invalid; 0.5 is fine.
- undefined isn't a JSON value. If a key's value would be undefined in JavaScript, it either gets dropped during serialization or needs to be represented as null.
Here's a piece of "JSON" that looks fine at a glance and breaks four of those rules at once:
{
name: 'Alex', // unquoted key, single quotes, comment
"age": 029,
"tags": ["a", "b",],
}A parser rejects every line of that. The corrected version:
{
"name": "Alex",
"age": 29,
"tags": ["a", "b"]
}Decoding common parser errors
When JSON.parse or an API client throws, the message usually looks cryptic but points at a small set of causes:
| Error message | What it usually means |
|---|---|
| Unexpected token ' in JSON | Single quotes used instead of double quotes |
| Unexpected token } or ] | A trailing comma right before the closing brace or bracket |
| Unexpected end of JSON input | The document was cut off — an unclosed brace, bracket, or string, or a truncated response |
| Unexpected token o in JSON at position 1 | You parsed something that was already an object, or the response was HTML ("<!DOCTYPE...") rather than JSON |
| Bad control character in string literal | A raw newline or tab inside a string — it needs to be escaped as \n or \t |
The "position 47" in these messages is a character offset into the raw text, which is nearly useless in a minified one-line payload — but becomes an exact line-and-column once the document is formatted. That alone is a good reason to format before debugging.
Numbers, precision, and other quiet gotchas
Some JSON problems don't throw errors at all — they silently corrupt data, which makes them worse:
- Big numbers lose precision. JavaScript reads JSON numbers as 64-bit floats, which are only exact for integers up to 2^53 − 1. IDs from large systems (databases, social platforms) routinely exceed this, which is why well-designed APIs send big IDs as strings:
"id": "9007199254740993". - Duplicate keys are legal-ish but dangerous. The spec doesn't forbid
{"a": 1, "a": 2}, and most parsers silently keep the last value. If two systems disagree on which value "wins", you get subtle bugs. - Key order is not guaranteed. JSON objects are unordered by definition. If your code depends on keys arriving in a particular order, it's depending on an implementation detail.
- "42" and 42 are different values. One is a string, one is a number. A type mismatch like this passes every syntax check and then breaks arithmetic or comparisons downstream — syntax highlighting in a formatter makes the difference visible at a glance.
Why formatting matters more than it seems
When JSON is minified — no line breaks, no indentation — a human reading it has to mentally track every open brace and bracket to figure out where one object ends and another begins. That's slow and error-prone, especially with deeply nested API responses.
A formatter (sometimes called a "beautifier" or "pretty-printer") does two things at once: it re-indents the structure so nesting is visually obvious, and it validates the syntax along the way. If something's broken — a missing comma, an unclosed bracket, a stray quote — a good formatter tells you the exact line and character where parsing failed, instead of leaving you to scan the whole document by eye.
That second part is the real time-saver. Debugging a malformed JSON payload by reading it character-by-character is tedious; letting a parser point at the exact failure is not.
The reverse operation matters too: minifying strips the whitespace back out for production, where those bytes are pure overhead. The practical rule is simple — pretty for humans, minified for machines. (Worth knowing: with gzip or brotli compression enabled on a server, the wire-size difference between the two shrinks a lot, so minification matters most for storage and uncompressed transfers.)
Try it yourself
Try it right here
JSON Formatter
Working with JSON in JavaScript
Two built-in methods do all the work, and both take underused extra arguments:
// String -> object. Throws on invalid input, so wrap risky sources.
const data = JSON.parse('{"name": "Alex", "age": 29}');
// Object -> string. The third argument is the indent width:
JSON.stringify(data, null, 2); // pretty, 2-space indented
JSON.stringify(data); // minified
// The second argument filters or transforms values on the way out:
JSON.stringify(data, ["name"]); // -> {"name":"Alex"}Two habits worth keeping: never use eval to read JSON (it executes anything malicious inside), and remember that JSON.stringify silently drops functions and undefined values — if a key vanishes from your output, that's usually why.
JSON in the wild
Once you start looking, JSON is carrying data in more places than API responses:
- Config files. package.json, tsconfig.json, and most modern tool configuration — which is where JSON's no-comments rule bites hardest, and why variants like JSONC exist.
- JWT tokens. The authentication tokens used across the web are three Base64-encoded segments, and two of them are JSON documents. Paste one into our JWT Decoder to see the JSON payload inside, or read our JSON Web Tokens handbook for the full picture.
- Structured data for SEO. Search engines read page metadata as JSON-LD — JSON with a vocabulary describing articles, products, and organisations. Our JSON-LD Schema Generator builds these blocks, and our technical SEO checklist covers where they fit.
- Data exchange everywhere else. Log lines, database exports, browser localStorage — JSON is the default container for structured data that has to move between systems.
From raw JSON to working code
Formatting is usually step one of a bigger task, and two follow-up jobs come up constantly in development work:
- Turning a payload into types. If you're consuming an API from TypeScript, our JSON to TypeScript converter generates interfaces from a sample response — paste the JSON, get the types, catch mismatches at compile time instead of runtime.
- Generating realistic test data. When you need sample payloads to develop against before a real API exists, our Mock Data Generator produces structured JSON records with names, emails, dates, and IDs in whatever shape you define.
When JSON is the wrong tool
JSON's strictness is a feature for machine-to-machine data, but it makes JSON genuinely bad at one job: files humans edit by hand. Knowing the alternatives saves fighting the format:
| Format | What it adds | Typical use |
|---|---|---|
| JSONC | Comments allowed | Editor and tool configs (VS Code uses it) |
| JSON5 | Comments, trailing commas, unquoted keys | Config files needing flexibility |
| YAML | Indentation-based, comments, multi-line strings | CI pipelines, infrastructure config |
| CSV | Rows and columns, opens in spreadsheets | Flat tabular data with no nesting |
The rule of thumb: JSON for data programs exchange, a comment-friendly variant for files people maintain, CSV when the data is a plain table.
A few debugging habits worth adopting
- Format API responses before reading them. Even if you're comfortable reading minified JSON, formatting surfaces structural issues faster than eyeballing it.
- Validate before you build logic around a payload. If a field you expect is buried three levels deep in an object you didn't know existed, you want to find that before writing code that assumes otherwise.
- Watch for type mismatches. JSON distinguishes "42" (a string) from 42 (a number) — a formatter that shows syntax highlighting makes this distinction obvious at a glance, which plain text doesn't.
- Keep an eye on encoding. JSON strings support Unicode escape sequences (\uXXXX); if you see unexpected characters, that's usually the cause.
Frequently asked questions
Is JSON the same as a JavaScript object?
JSON.stringify() and JSON.parse() are the bridge between the two.Why does my JSON fail to parse even though it looks fine?
Can JSON store dates?
What is the difference between JSON and JSON5?
Is it safe to parse JSON from an unknown source?
JSON.parse itself is safe — it only produces data, never executes code, which is exactly why it should always be used instead of eval. The care belongs one step later: validate the parsed data's shape and types before your code trusts it.How do I handle very large JSON files?
Hands on
Tools mentioned in this article
JSON Formatter
Validate, format, and minify JSON with 2-space, 4-space, or tab indentation, size statistics, copying, and download.
JWT Decoder
Decode JWT header, payload, signature, registered claims, and expiry, with optional client-side HMAC verification for HS256, HS384, and HS512.
JSON-LD Schema Generator
Fill a short form and get a valid JSON-LD script tag for Article, WebSite, FAQ, Product, or Organization structured data.
JSON to TypeScript
Generate TypeScript interfaces from valid JSON objects and nested API-response samples, with copying and `.ts` download.
More guides
Keep reading

How to calculate EMI on any loan
The EMI formula explained in plain terms, a worked example, and what actually happens to your money over the life of a loan.

Password best practices in 2026
Why length beats complexity, how passphrases work, and a realistic system for managing passwords without losing your mind.

The Ultimate Guide to JSON Web Tokens (JWT) in 2026
A comprehensive, beginner-friendly guide to understanding JSON Web Tokens (JWTs), how they work, common use cases, and security best practices.
Put it into practice
Every guide comes with free tools to match.
Public tools open without sign-up. Local, upload, AI, and premium workspace steps are labeled clearly.