Skip to content

Working with JSON, explained

JSON is one of those formats people use constantly and still trip over. It looks simple enough to type by hand. Then a missing comma, a stray quote, or an unexpected shape breaks a request, a config file, or a build step.

That is because JSON is doing two jobs at once. It is meant to be readable enough for humans to inspect, and strict enough for machines to parse reliably. Those goals meet in a format that feels lightweight right up until a parser points at character 248 and says the whole document is invalid.

This guide covers the parts of JSON work that come up most often: the syntax rules, when formatting helps, when minifying helps, how JSONPath queries fit in, why YAML conversion can be useful, how generated TypeScript types help catch shape mismatches, and which parse errors show up again and again.

What JSON is

JSON stands for JavaScript Object Notation, but it is not just for JavaScript. It is a text format for structured data, used in APIs, config files, logs, exports, fixtures, and data pipelines everywhere.

JSON is built from a small set of data types:

  • objects
  • arrays
  • strings
  • numbers
  • booleans
  • null

A small example:

{
  "user": {
    "id": 42,
    "name": "Sam",
    "active": true
  },
  "roles": ["admin", "editor"],
  "lastLogin": null
}

That is not a lot of syntax to learn. The trick is being strict about it.

The syntax rules that matter most

JSON is picky in predictable ways.

Here are the rules that cause the most trouble:

  • object keys must be in double quotes
  • strings use double quotes, not single quotes
  • items need commas between them
  • no trailing comma after the last item
  • values must be valid JSON types
  • comments are not part of standard JSON

So this is valid:

{
  "name": "Sam",
  "count": 3
}

And this is not:

{
  name: 'Sam',
  count: 3,
}

Why? The key is unquoted, the string uses single quotes, and the last property has a trailing comma.

These rules feel fussy until you remember what JSON is trying to do: travel cleanly across systems and parse the same way everywhere.

Formatting versus minifying

Formatting and minifying use the same data. They only change how the text is laid out.

Formatting

Formatting adds indentation and line breaks so humans can read the structure more easily.

Good times to format JSON:

  • inspecting an API response
  • reviewing config changes
  • debugging nested data
  • comparing two related payloads

Pretty-printed JSON is slower to scan as raw bytes but much easier to understand at a glance.

Minifying

Minifying removes unnecessary whitespace so the text is smaller.

Good times to minify JSON:

  • sending compact payloads over the wire
  • embedding JSON where size matters
  • preparing machine-only output

Minification does not change the meaning of the data. It just removes visual breathing room.

The practical rule is simple: format for people, minify for transport or storage when whitespace overhead matters.

Objects, arrays, and shape

Much of "working with JSON" is really working with shape.

An object is good for named fields:

{
  "id": 42,
  "name": "Sam"
}

An array is good for ordered lists:

[
  "admin",
  "editor"
]

The moment shape drifts, bugs start showing up:

  • code expects an object and gets an array
  • a field that used to be a string becomes null
  • a nested property moves or disappears
  • a number arrives as a quoted string

That is why tooling around JSON matters so much. It is rarely the syntax alone. It is syntax plus shape plus assumptions in the code that consumes the data.

JSONPath and querying JSON

Once a JSON document gets large, scrolling through it stops being fun. That is where JSONPath helps.

JSONPath is a query language for selecting parts of a JSON document. Think of it as a way to point at exactly the piece you want.

Depending on the implementation, examples may look like:

  • $.user.name
  • $.roles[*]
  • $.orders[0].total
  • $.items[?(@.active==true)]

The exact feature set can vary by tool or library, but the core idea is the same: instead of manually digging through the whole tree, you write a path or filter to extract what matters.

That is useful for:

  • debugging API responses
  • testing nested fields
  • pulling values from config dumps
  • checking whether repeated items meet some condition

YAML conversion

JSON and YAML overlap a lot. Both can describe structured data, but YAML is often friendlier for hand-edited configuration because it can be less visually noisy.

So why convert between them?

  • an API or export gave you JSON but the target tool expects YAML
  • you want a more human-friendly config file for editing
  • you need to move data between ecosystems that prefer different formats

The caution here is that YAML has features and edge cases JSON does not. A conversion can preserve the data while changing how some values are interpreted if you are not careful. That is another reason to treat the converted result as something to inspect, not just assume.

Generated TypeScript types

If JSON is entering an application, especially a TypeScript application, generated types can save real time.

Say an API response has this shape:

{
  "user": {
    "id": 42,
    "name": "Sam",
    "active": true
  },
  "roles": ["admin", "editor"]
}

A TypeScript type generator can turn that into interfaces or types that your code can use directly. That helps with:

  • autocomplete
  • safer property access
  • catching shape mismatches at compile time
  • documenting expected data structures

Generated types are not a guarantee that runtime data is correct, but they do help keep assumptions visible instead of scattered through a codebase.

A worked example across formatting, querying, and types

Start with a compact JSON payload:

{"user":{"id":42,"name":"Sam","active":true},"roles":["admin","editor"],"settings":{"theme":"dark","beta":false}}

First, format it:

{
  "user": {
    "id": 42,
    "name": "Sam",
    "active": true
  },
  "roles": ["admin", "editor"],
  "settings": {
    "theme": "dark",
    "beta": false
  }
}

Now the structure is readable. You can see three top-level keys, a nested user object, and a settings object.

Next, query it with JSONPath.

If you want the user name, a path like:

$.user.name

selects "Sam".

If you want every role:

$.roles[*]

selects "admin" and "editor".

If you want to know whether beta mode is on:

$.settings.beta

selects false.

Now turn that same JSON shape into TypeScript types:

interface User {
  id: number;
  name: string;
  active: boolean;
}

interface Settings {
  theme: string;
  beta: boolean;
}

interface Root {
  user: User;
  roles: string[];
  settings: Settings;
}

That is the bigger lesson. One JSON document can support several different tasks:

  • readable inspection through formatting
  • focused extraction through JSONPath
  • safer application code through generated types

Common parse errors

Most JSON parse errors are boring once you know what to look for.

The usual suspects:

Missing comma

{"a": 1 "b": 2}

Trailing comma

{"a": 1,}

Single quotes

{'a': 1}

Unquoted key

{a: 1}

Bad string escaping

{"path": "C:\new\file"}

That last one is a classic because backslashes in strings need escaping. The parser is not being rude. It is being exact.

Try the browser tools

These all run in your browser and cover different parts of the same JSON workflow:

  • JSON Formatter — turn dense JSON into readable structure for inspection and debugging.
  • JSON Minifier — remove whitespace when you want compact machine-oriented output.
  • JSONPath Tester — try queries against nested JSON without wiring up code first.
  • JSON YAML Converter — move the same data between two common structured-text formats.
  • JSON to TypeScript — generate useful type shapes from real data examples.

Taken together, they make a nice progression: parse it, read it, query it, convert it, and turn the shape into code.

Common mistakes

Treating JavaScript object literal syntax as JSON. They overlap, but they are not the same format.

Editing minified JSON by hand. You can do it, but you are making your own life harder.

Assuming a field always exists because it existed once. That is a shape assumption, not a guarantee.

Using regex instead of a parser for real JSON work. Regex can help with simple text checks, but JSON is structured data. Use structured tools when structure matters.

Forgetting that YAML conversion can change expectations around formatting and typing. Always inspect the output.

FAQ

No. JSON is a text format. A JavaScript object is a runtime data structure. One can be parsed into the other, but they are not the same thing.

Usually because of one of the strict syntax rules: quotes, commas, escaping, comments, or trailing commas.

When humans do not need to read it and size matters more than readability.

Finding and extracting parts of a nested JSON document without writing a whole parser or a custom traversal.

It is often a good starting point, especially for internal tools and API exploration. Just remember that sample-driven types reflect the sample you gave them, not every possible payload your system might return.

Related guides