Learn JSON

I get asked “who made JSON?” more often than you’d think, usually while someone is staring at a minified API response. This is the version I tell people, with the dates attached so I don’t mix up RFC numbers again.

JSON is just text. Curly braces for objects, square brackets for lists, double quotes on strings. Booleans, numbers, null. That’s the whole type list. No dates, no comments, no binary. You can paste examples into the editor if you’d rather poke at them than read.

It looks like JavaScript. It isn’t.

Early on, some folks literally eval’d a JSON response. Please don’t. Use JSON.parse. The syntax was chosen so a JS engine could swallow it, which was a clever hack in 2001 and a foot-gun later. JSON also refuses things JavaScript allows: single quotes, unquoted keys, a comma after the last field.

{
    "format": "JSON",
    "yearNamed": 2001,
    "open": true,
    "related": ["XML", "YAML", "BSON"]
}

What we used before

If you were building “Ajax” sites around 2000, the fashionable payload was XML. Microsoft’s XMLHTTP (then XMLHttpRequest) made it possible to fetch without reloading the page. XML had tools. It also had a lot of angle brackets. Nested maps in a script wanted to look like nested maps, not another document tree.

People already cheated with JavaScript object literals in HTTP bodies. Somebody had to name the cheat, write a grammar other languages could implement, and put it on a website.

Crockford, State Software, json.org

That somebody was Douglas Crockford, around 2001, at State Software (he co-founded it). He did not invent {} and []. Brendan Eich did that in JavaScript at Netscape in 1995. Crockford sliced out a data-only subset, named it JSON (he’s said it was a bit of a joke that sounded like “Jason”), and later put up json.org with those railroad diagrams everyone still screenshots.

He cared that it wouldn’t be wrapped in patents. That’s not a cute slogan; it’s why every language grew a library instead of waiting for a vendor.

Libraries, Yahoo, then the browser itself

json.org listed ports for Java, C#, Python, PHP, Perl, Ruby… XML already had that ubiquity. JSON needed it or it would have stayed a JS party trick. Yahoo used it a lot. For years we shipped Crockford’s json2.js because browsers had no JSON object.

December 2009: ECMAScript 5. Native parse / stringify. Faster, and you could stop eval’ing. That, more than any blog post, made JSON “just how the web works.”

The RFCs, because a website isn’t a spec

RFC 4627 (July 2006, Crockford) registered application/json. Odd leftover from that version: the top level had to be an object or array. A lone true wasn’t a “JSON text” yet.

Ecma published ECMA-404 in October 2013 so it wasn’t “IETF vs some JS guy’s homepage.” RFC 7159 (Tim Bray, March 2014) killed 4627 and allowed any value at the root. Duplicate keys: don’t. Parsers disagree on first-vs-last and you will lose an afternoon.

What I actually bookmark now is RFC 8259 (December 2017, STD 90), still Bray, still lined up with ECMA-404. UTF-8 for interchange. That’s the internet’s JSON.

Why it’s so stubbornly small

No comments means two parsers can’t fight about comment syntax. No trailing commas. Numbers aren’t “ints vs floats” in the grammar, which still annoys Java and Go people. That’s why JSONC, JSON5, Hjson exist — humans editing files. They are not JSON. Auto Fix on this site exists because I kept pasting VS Code settings into a JSON.parse box.

XML, YAML, and the binary cousins

XML still wins at mixed content (words with tags inside) and a pile of enterprise schemas. JSON won public HTTP APIs because it was smaller and mapped onto objects we already had in memory.

YAML is nicer to type by hand and has bitten people with surprise types. I keep APIs in JSON and let humans have YAML if they insist. BSON, MessagePack, CBOR, protobuf — same nested-map idea, less UTF-8, when you’re tired of parsing text at 100k QPS.

APIs, package.json, databases

By the 2010s if your mobile app talked to a server, the body was probably JSON. GitHub, OAuth token endpoints, old Twitter REST, you name it. GraphQL queries aren’t JSON; the typical HTTP wrapping still is.

Node made package.json inescapable. Then every other tool copied the idea. MongoDB says JSON and stores BSON (dates, object ids). CouchDB actually was JSON over HTTP. Document stores existed before JSON; JSON gave them a dialect everyone could read in a textarea.

Schema and patches, bolted on later

JSON itself has no schema. JSON Schema (community drafts, OpenAPI shapes) is how we document APIs anyway. JSON-LD is still JSON text plus a @context so keys mean URLs; search engines like it in a script tag. JSON Pointer / Patch / Merge Patch (6901, 6902, 7396) treat the document as a tree — same tree the viewer on the home page draws.

The security chapter nobody enjoyed

JSON-as-<script> and eval led to hijacks. Some APIs prefixed while(1); as a weird bandage. JSON.parse plus same-origin fetch mostly ended that era. What’s left is boring and real: dumping JSON into HTML, prototype pollution when you Object.assign blindly, giant numbers overflowing in languages with fixed ints, duplicate keys.

Still here in 2026

gRPC and friends exist. Browsers still speak JSON in fetch without asking anyone. Crockford’s bet was “keep it tiny and unencumbered.” The RFCs showed up later to stop implementations drifting. That’s the whole story, really.

If you want to click around instead of reading RFCs: Format, Auto Fix, tree.

Dates I keep on a sticky note