Six Characters That Ate the Web: The History of JSON
· 10 min read
Open the network tab on almost any website and watch the requests go by. Most of the responses will look the same: curly braces, square brackets, quoted names, colons and commas. The weather on your phone, the items in your cart and the messages in your chat app all arrive in that shape.
That format is JSON, short for JavaScript Object Notation. Its whole structure is built from six characters, { } [ ] : and ,, plus strings, numbers, true, false and null. It has no comments, no dates and no version number, and that is mostly on purpose. The story of how it took over includes a failed test message, a website with no owner, a software licence that banned evil, and an integer limit that forced Twitter to send every ID twice.
A broken message in 2001
In 2001, Douglas Crockford and Chip Morningstar co-founded a company called State Software. They wanted to build web applications that kept a live connection between the browser and the server, years before that was common. The obvious choice for sending data back and forth was XML, but parsing XML in the browsers of 2001 was slow and awkward.
Crockford noticed that the browser already had a parser for structured data: JavaScript itself. A JavaScript object literal could describe nested records, lists, strings and numbers, and the browser could turn that text into a live object by evaluating it. No extra library was needed.
The team sent its first message this way in April 2001, and it failed. One of the keys in the object was do, which is a reserved word in JavaScript, and the browsers of the time refused to accept a reserved word as an unquoted property name. Rather than publish a list of words to avoid, Crockford made a simpler rule: every key is a quoted string. That is why JSON still requires "name" where JavaScript would happily take name.
The format needed a name. The team first considered JSML, for JavaScript Markup Language, but that acronym was already taken by the Java Speech Markup Language. They settled on JSON.
Discovered, not invented
Crockford has always said he didn't invent JSON. The syntax was already part of JavaScript, and other programmers had been passing object literals around in the same way. What he did was give the idea a name, write down exactly which parts of JavaScript counted, and put it on a website.
That website, json.org, went up in 2002. It is still a single page: a short description, a set of railroad diagrams that define the whole grammar, and a long list of parsers in other languages. Crockford liked to point out that the full grammar fits on the back of a business card, and that was a big part of the appeal. A programmer could write a JSON parser in an afternoon, and over the next few years people did that for almost every language in use.
The reference code Crockford published carried an unusual licence. It was the standard MIT licence with one extra line: the software shall be used for good, not evil. Open source distributions such as Debian treated the clause as a restriction and declined to ship that code. IBM's lawyers asked Crockford for an exemption for his JSLint tool, which carried the same clause, and he wrote back granting IBM and its customers permission to use it for evil.
Leaving things out
Most of JSON's design is about what it doesn't allow.
{
"id": 1042,
"name": "Ada",
"tags": ["admin", "beta"],
"active": true,
"manager": null
}
That example uses almost every feature the format has. There are objects, arrays, strings, numbers, booleans and null, and nothing else.
No comments. Early drafts allowed them. Crockford removed them after seeing people use comments to carry instructions for their own parsers, which meant a file could mean different things to different programs. Without comments, a JSON document means the same thing everywhere. If you want to annotate it, he suggested, add a field or strip the comments out before parsing.
No dates. JSON has no date type, so every API has to pick a convention. The two common ones are an ISO 8601 string like "2026-10-12T09:30:00Z" or a number of seconds since 1970, the counter described in our history of Unix time.
No special numbers. NaN and Infinity are not valid JSON, and neither are leading zeros, hexadecimal or a leading plus sign.
No trailing commas, no single quotes. Both are common in JavaScript and both are errors in JSON. They account for a large share of the parse errors people run into when they edit JSON by hand.
No version number. Crockford's position was that JSON was finished. A format that never changes can't have version mismatches, so there is no JSON 2.0 and there was never meant to be one.
Check a JSON file for errorsFormat, validate, and minify JSON with precise, human-readable error locations. Fast, local, and safe for sensitive data.The X in AJAX
When JSON appeared, XML was the standard for exchanging data. It became a W3C recommendation in 1998, and by the early 2000s it was the basis for SOAP web services, RSS feeds, configuration files and office documents. Enterprise software vendors had built large toolsets around it.
In February 2005, the designer Jesse James Garrett published an essay naming the technique behind Gmail and Google Maps: pages that fetched data in the background and updated without reloading. He called it AJAX, for Asynchronous JavaScript and XML. The name put XML at the centre, but developers who actually built AJAX pages kept finding JSON easier. A JSON response became a JavaScript object in one step. An XML response had to be walked node by node through the DOM.
Yahoo! began offering some of its web services as JSON in December 2005, and other large APIs followed over the next few years. By the early 2010s, new public APIs were more likely to be JSON-only than XML-only.
There was one serious problem. The easy way to parse JSON in a browser was eval(), which runs any JavaScript it is given. If a server, or anyone who could tamper with its response, sent code instead of data, the browser would execute it. Crockford published json2.js, a small library that checked the text before evaluating it. Browsers then added native parsers, and ECMAScript 5, in December 2009, made JSON.parse and JSON.stringify part of the language.
Becoming a standard
JSON spread for years before anyone formally standardised it.
| Year | Milestone |
|---|---|
| 2001 | First JSON message sent at State Software |
| 2002 | json.org goes online |
| 2005 | "AJAX" is coined; Yahoo! starts serving JSON |
| 2006 | RFC 4627 registers the application/json media type |
| 2009 | ECMAScript 5 adds JSON.parse and JSON.stringify to JavaScript |
| 2013 | ECMA-404 publishes the grammar as an international standard |
| 2017 | RFC 8259 makes JSON an Internet Standard and requires UTF-8 between systems |
| 2019 | ES2019 finally makes every JSON text valid JavaScript |
That last line is a quirk. For almost twenty years, JSON was described as a subset of JavaScript, and it wasn't quite one. JSON strings could contain two invisible Unicode characters, the line separator U+2028 and the paragraph separator U+2029, without escaping them. JavaScript string literals could not. A JSON document containing either character would parse with JSON.parse but fail as JavaScript source. ES2019 changed JavaScript to allow them, so the description became true.
The 2⁵³ problem
The JSON grammar puts no limit on numbers. A number can have as many digits as you like. The programs that read JSON do have limits, and the most important one is JavaScript's.
JavaScript stores every number as a 64-bit floating-point value. That format can represent every integer exactly only up to 2⁵³ − 1, which is 9,007,199,254,740,991. Above that, some integers can't be represented and get rounded to the nearest one that can.
Twitter ran into this in 2010. It was switching tweet IDs to a new scheme called Snowflake, which built 64-bit IDs from a millisecond timestamp, a machine number and a sequence counter. Those IDs were too large for JavaScript to hold exactly. A browser that read a tweet ID from JSON could silently change its last few digits and end up pointing at a different tweet. Twitter's fix was to send each ID twice: once as a number, id, and once as a string, id_str. Developers were told to use the string.
Many APIs now do the same thing and send large IDs, account numbers and money amounts as strings. JavaScript's BigInt type doesn't fix this on its own, because JSON.stringify throws a TypeError when it meets a BigInt value instead of guessing how to write it.
What grew around it
Because JSON itself never changes, everything people wanted from it was built on top.
JSON Schema describes what a JSON document should contain, which fields are required and what types they hold. It is used to validate API requests, generate forms and document configuration files.
JSONPath gives JSON a query language. Stefan Goessner proposed it in 2007 as an equivalent of XPath for XML, and after many slightly different implementations it was standardised as RFC 9535 in 2024. A query like $.store.book[*].author pulls every author out of a nested document.
JSON Lines, also called newline-delimited JSON, puts one JSON value per line. It suits logs and large datasets because a program can read one record at a time without loading the whole file.
JSON-LD adds linked-data meaning to ordinary JSON. It is the format Google recommends for structured data, so it is in the <head> of many pages to describe products, recipes, articles and events to search engines.
Other formats added back what JSON left out. JSON5 and the JSONC variant used by VS Code and tsconfig.json allow comments and trailing commas, which makes them easier to edit by hand. YAML 1.2, released in 2009, was revised so that nearly every JSON document is also valid YAML. That is why converting between the two is usually straightforward in one direction and more involved in the other.
Still the same six characters
JSON became the default because it left so much out. A format with no comments, no dates, no versions and no extensions sounds limited, and in some ways it is. But it also means a parser written in 2003 can read a document written today, and a document written in Python can be read in Go, Rust or a browser without anyone agreeing on anything beyond one page of grammar.
Crockford didn't design a format for the whole web. He was trying to get a message from a server to a browser in 2001 without a plugin, and a reserved word got in the way. The quoted keys, the strict commas and the missing comments that came out of that are now in nearly every API request on the internet.
Format and validate your JSONFormat, validate, and minify JSON with precise, human-readable error locations. Fast, local, and safe for sensitive data.