You're poking around a REST API response for the first time and the terminal spits out something like {"id":42,"name":"Alice","active":true}. At first glance it looks vaguely like a Python dict, vaguely like a JavaScript object — and that's basically the point. That's JSON, and once it clicks, you'll see it everywhere.
JSON stands for JavaScript Object Notation. Douglas Crockford formalized it in the early 2000s as a lightweight alternative to XML, and it took over web development almost completely within a decade. Today it's the de-facto format for REST APIs, configuration files, log aggregation pipelines, NoSQL databases — the list goes on. It won not because it's perfect, but because it's simple enough that almost nothing can go wrong with it.
The two building blocks
Everything in JSON is made of just two structures: objects (key-value maps) and arrays (ordered lists). That's really it. Nest them as deep as you need.
{
"user": {
"id": 101,
"name": "Alice",
"roles": ["admin", "editor"],
"address": {
"city": "Berlin",
"zip": "10115"
},
"active": true,
"score": 98.6,
"notes": null
}
}
Reading this, you immediately know what you're dealing with without any documentation. That's the whole selling point.
Six data types, no more
JSON is deliberately limited. It only has six types, and that constraint is a feature — it removes ambiguity.
Notice there's no native date type. This trips up a lot of developers early on — you hit an API endpoint and get back "created_at": "2026-03-01T00:00:00Z" and wonder why it's a string. It's always been a string. The convention is ISO 8601, but the spec doesn't enforce anything. Every API basically decides this on its own.
Why it beat XML
If you ever had to work with XML-based APIs (SOAP, anyone?), you remember the pain. Fetching a user's name from an XML response meant writing a namespace-aware XPath query, dealing with mixed content nodes, and hoping the schema was documented somewhere. JSON just... doesn't have those problems.
The same data that takes 400 bytes in XML might take 200 bytes in JSON. The parsing is faster, the readability is better, and there's no attribute-vs-element debate to have. The only real thing XML has over JSON is comments — JSON has no comment syntax at all, which is a genuine annoyance when writing config files.
The errors that will ruin your afternoon
JSON looks simple until you're staring at a parse error at 11pm. Here are the ones that come up constantly:
Trailing commas. This is the big one. Almost every other language forgives a trailing comma in a list. JSON does not.
// This will fail
{
"name": "Alice",
"age": 30,
}
// This is correct
{
"name": "Alice",
"age": 30
}
Single quotes. If you're coming from Python or JavaScript (where single quotes are fine), muscle memory will bite you. JSON requires double quotes for all strings, including keys.
// Wrong
{ 'name': 'Alice' }
// Right
{ "name": "Alice" }
Unquoted keys. This one often shows up when copying from JavaScript object literals. In JS, { name: "Alice" } is valid — in JSON it isn't.
Comments. There are none. // comment inside a .json file will throw a parse error. If you need comments in config files, consider JSONC (used by VS Code's settings.json) or switch to YAML.
Where JSON actually lives
The most common place you'll encounter JSON is API responses. A typical fetch() call in the browser looks like:
const res = await fetch('/api/users/42');
const user = await res.json(); // JSON → JS object
On the server side, your package.json is JSON. So is tsconfig.json, .eslintrc.json, and a hundred other tool configs. The moment you install a Node project, you're already swimming in JSON.
NoSQL databases like MongoDB serialize your documents as BSON (Binary JSON) internally. PostgreSQL has a native jsonb column type. Even some SQL queries return JSON now. It's unavoidable.
A mental model for JSON structure
The key insight is that JSON is always a tree. Every value is either a leaf (string, number, boolean, null) or a branch (object or array) that contains more nodes. Once you visualize it that way, navigating deeply nested responses becomes intuitive — you just traverse the tree.
Validating and formatting JSON in practice
Paste a 2000-line API response into your editor and try to find the missing closing brace by eye. It's not fun. The smarter approach is to pipe it through a formatter — either jq in the terminal (cat response.json | jq .) or a proper online tool where you can see the structure and error messages clearly.
If you want to quickly check whether some JSON is valid, or clean up minified output into something readable, try the JSON Formatter & Validator — it highlights errors inline and lets you collapse and expand nested objects.
JSON is one of those things that takes about 20 minutes to learn and then you use every single day. The gotchas are real but finite. Once you've hit the trailing-comma error enough times, you stop making it.