When an app shows today's weather, it asks a server for the data. The server has to send that data as plain text, because text is something every computer, language and network understands. But the data has structure: a city, a temperature, a list of hourly forecasts. How do you squeeze structure into text so the other side can rebuild it exactly?
The most common answer on the web is JSON, short for JavaScript Object Notation. It started as a way of writing JavaScript values as text, but today almost every language can read and write it. Python, Ruby, Go, Rust, Java and the rest all ship with a JSON tool. If you call a web API (a service your code can ask for data), the reply is very likely JSON.
JSON has a tiny vocabulary. Every piece of JSON is one of these:
| Kind | Example | Notes |
|---|---|---|
| string | "hello" | always double quotes |
| number | 12, -3.5, 1e3 | one kind of number, no quotes |
| boolean | true, false | lowercase |
| null | null | "nothing here" |
| array | ["chess", "tea"] | an ordered list |
| object | {"name": "Mia"} | named values; the names are called keys |
Arrays and objects can hold any of the six kinds, including other arrays and objects, so you can nest them as deep as you need. That is how a flat piece of text describes a whole tree of data.
Below is a live JSON editor. It hands your text to the same JSON.parse function your browser gives to every web page. Parsing means reading text and turning it into data the program can use. Edit the text, or press a button to load a classic mistake, and watch what the parser says. The error wording comes from your own browser, so it may read a little differently from the examples later in this article.
JSON looks like JavaScript, but it is stricter. Those buttons above showed the usual traps:
Double quotes only. 'Mia' is fine in JavaScript and an error in JSON. Keys are always strings in double quotes, so {name: "Mia"} fails. No trailing commas: a comma after the last item is an error. No comments, and no undefined, functions or NaN; there is no way to write those. If you need "no value", use null.
This strictness is a feature. A small, rigid format leaves no room for two programs to read the same text differently.
In JavaScript, JSON.parse turns text into data and JSON.stringify turns data into text. Here is a run with Node.js 22:
const text = '{"name":"Mia","age":12,"likes":["chess","tea"],"pet":null,"vip":true}';
const data = JSON.parse(text);
console.log(data.name, data.likes[1], typeof data.age);
console.log(JSON.stringify({ name: "Mia", age: 12 }));
Output:
Mia tea number
{"name":"Mia","age":12}
Python does the same job with the json module. Notice how the words change: JSON's true and null become Python's True and None.
import json
text = '{"name": "Mia", "age": 12, "likes": ["chess", "tea"], "pet": null, "vip": true}'
data = json.loads(text)
print(data["name"], data["likes"][1], type(data["age"]).__name__, data["pet"], data["vip"])
print(json.dumps({"name": "Mia", "vip": True, "pet": None}))
Output (Python 3):
Mia tea int None True
{"name": "Mia", "vip": true, "pet": null}
That is the whole point of JSON: the same text on the wire, and each language turns it into its own natural types.
JSON can only hold those six kinds, so anything else has to be squeezed into them. Try this in JavaScript:
const x = { when: new Date(Date.UTC(2026, 9, 4)), skip: undefined, bad: NaN, n: null };
console.log(JSON.stringify(x));
{"when":"2026-10-04T00:00:00.000Z","bad":null,"n":null}
Three things happened. The date became a plain string; when you parse it back you get text, not a date, so you must convert it yourself. The undefined value vanished, key and all. And NaN turned into null. Functions are dropped in the same way as undefined. If your data seems to lose things after a round trip, this is the first place to look.
A parse error nearly always means the text is not JSON at all, or was cut off. Here are real messages from Node.js 22 for text a beginner might actually paste (other browsers word them differently):
| Text | Message |
|---|---|
{"a":1,} | Expected double-quoted property name in JSON at position 7 (line 1 column 8) |
[1,2 | Expected ',' or ']' after array element in JSON at position 4 (line 1 column 5) |
{"a":undefined} | Unexpected token 'u', "{"a":undefined}" is not valid JSON |
| (empty string) | Unexpected end of JSON input |
"Unexpected end of JSON input" is the one you will meet most. It usually means the server sent nothing, or the reply stopped halfway. The position number counts characters from zero, which is why the editor above can highlight the exact spot for you.
When you call an API, you will get a string of JSON, parse it into data, read the parts you need, and later stringify your own data to send back. When something fails, paste the text into a validator (or the editor above) before you debug anything else. Most of the time the answer is a stray comma, a single quote, or a reply that was never JSON in the first place.