Skip to content
motifuse
Guide
11 min read

What is JSON and how to format it correctly

A practical guide to JSON syntax, the mistakes that break it, and how a formatter turns a wall of text into something you can actually debug.

The motifuse team

Updated

If you've worked with an API, a config file, or a browser's network tab, you've run into JSON. It's the format most web services use to send data back and forth, and it's popular for a simple reason: it's small, it's readable by both humans and machines, and almost every programming language can parse it without extra libraries.

But "readable" only holds up when the JSON is formatted. A 200KB API response returned as one unbroken line of text is technically valid JSON — and completely useless to look at. That's the gap a formatter fills.

Where JSON came from

JSON stands for JavaScript Object Notation, and it was popularised in the early 2000s by Douglas Crockford, who famously said he didn't invent it so much as discover it — the syntax already existed inside JavaScript. At the time, the dominant data format for web services was XML, which wrapped every value in opening and closing tags and needed dedicated parsers to read. JSON expressed the same data in a fraction of the bytes, mapped directly onto the data structures most languages already had (objects, arrays, strings, numbers), and could be parsed natively in the browser. The result: as browser-based apps took over, JSON quietly became the default language of APIs, and today formats like configuration files, log streams, and even database documents speak it.

The basic building blocks

JSON has exactly two container types, and everything is built from them:

  • Objects — unordered collections of key/value pairs, wrapped in curly braces: {"name": "Alex", "active": true}
  • Arrays — ordered lists of values, wrapped in square brackets: ["red", "green", "blue"]

Values inside either one can be a string, a number, a boolean, null, or another object or array — which is how you get deeply nested structures like a list of users, each with their own address object, each containing its own fields:

json
{
  "users": [
    {
      "name": "Alex",
      "active": true,
      "address": {
        "city": "Kochi",
        "pincode": "682001"
      },
      "roles": ["editor", "admin"]
    }
  ],
  "total": 1
}

That's the entire compositional model. Every JSON document you'll ever meet — a 50MB API dump or a three-line config — is just these pieces nested inside each other.

Every value type at a glance

TypeExampleNotes
String"hello"Double quotes only; supports \n, \", \\ and \uXXXX escapes
Number42, -3.14, 2.5e10No leading zeros, no trailing dot, no NaN or Infinity
Booleantrue, falseLowercase only
NullnullThe only "empty" value; undefined does not exist in JSON
Object{"key": "value"}Keys must be double-quoted strings
Array[1, "two", null]Values can be of mixed types

The rules that trip people up

JSON looks like a JavaScript object literal, which is exactly why people assume JavaScript's more relaxed rules apply. They don't. JSON has a stricter, fixed grammar:

  • Keys must be strings, and they must use double quotes. {"name": "Alex"} is valid; {name: "Alex"} is not, and neither is {'name': 'Alex'}.
  • Single quotes are never allowed, for keys or values.
  • No trailing commas. ["a", "b",] fails to parse — that dangling comma after the last item is a syntax error, even though it's harmless in JavaScript arrays.
  • No comments. Not // and not /* */. The JSON spec deliberately leaves comments out, which is why config formats like JSON5 or YAML exist for cases where you actually want to annotate your data.
  • Numbers can't have leading zeros or a trailing decimal point — 01 and 5. are both invalid; 0.5 is fine.
  • undefined isn't a JSON value. If a key's value would be undefined in JavaScript, it either gets dropped during serialization or needs to be represented as null.

Here's a piece of "JSON" that looks fine at a glance and breaks four of those rules at once:

json
{
  name: 'Alex',        // unquoted key, single quotes, comment
  "age": 029,
  "tags": ["a", "b",],
}

A parser rejects every line of that. The corrected version:

json
{
  "name": "Alex",
  "age": 29,
  "tags": ["a", "b"]
}

Decoding common parser errors

When JSON.parse or an API client throws, the message usually looks cryptic but points at a small set of causes:

Error messageWhat it usually means
Unexpected token ' in JSONSingle quotes used instead of double quotes
Unexpected token } or ]A trailing comma right before the closing brace or bracket
Unexpected end of JSON inputThe document was cut off — an unclosed brace, bracket, or string, or a truncated response
Unexpected token o in JSON at position 1You parsed something that was already an object, or the response was HTML ("<!DOCTYPE...") rather than JSON
Bad control character in string literalA raw newline or tab inside a string — it needs to be escaped as \n or \t

The "position 47" in these messages is a character offset into the raw text, which is nearly useless in a minified one-line payload — but becomes an exact line-and-column once the document is formatted. That alone is a good reason to format before debugging.

Numbers, precision, and other quiet gotchas

Some JSON problems don't throw errors at all — they silently corrupt data, which makes them worse:

  • Big numbers lose precision. JavaScript reads JSON numbers as 64-bit floats, which are only exact for integers up to 2^53 − 1. IDs from large systems (databases, social platforms) routinely exceed this, which is why well-designed APIs send big IDs as strings: "id": "9007199254740993".
  • Duplicate keys are legal-ish but dangerous. The spec doesn't forbid {"a": 1, "a": 2}, and most parsers silently keep the last value. If two systems disagree on which value "wins", you get subtle bugs.
  • Key order is not guaranteed. JSON objects are unordered by definition. If your code depends on keys arriving in a particular order, it's depending on an implementation detail.
  • "42" and 42 are different values. One is a string, one is a number. A type mismatch like this passes every syntax check and then breaks arithmetic or comparisons downstream — syntax highlighting in a formatter makes the difference visible at a glance.

Why formatting matters more than it seems

When JSON is minified — no line breaks, no indentation — a human reading it has to mentally track every open brace and bracket to figure out where one object ends and another begins. That's slow and error-prone, especially with deeply nested API responses.

A formatter (sometimes called a "beautifier" or "pretty-printer") does two things at once: it re-indents the structure so nesting is visually obvious, and it validates the syntax along the way. If something's broken — a missing comma, an unclosed bracket, a stray quote — a good formatter tells you the exact line and character where parsing failed, instead of leaving you to scan the whole document by eye.

That second part is the real time-saver. Debugging a malformed JSON payload by reading it character-by-character is tedious; letting a parser point at the exact failure is not.

The reverse operation matters too: minifying strips the whitespace back out for production, where those bytes are pure overhead. The practical rule is simple — pretty for humans, minified for machines. (Worth knowing: with gzip or brotli compression enabled on a server, the wire-size difference between the two shrinks a lot, so minification matters most for storage and uncompressed transfers.)

Try it yourself

Try it right here

JSON Formatter

Open full tool
Loading embedded tool...

Working with JSON in JavaScript

Two built-in methods do all the work, and both take underused extra arguments:

javascript
// String -> object. Throws on invalid input, so wrap risky sources.
const data = JSON.parse('{"name": "Alex", "age": 29}');

// Object -> string. The third argument is the indent width:
JSON.stringify(data, null, 2);   // pretty, 2-space indented
JSON.stringify(data);            // minified

// The second argument filters or transforms values on the way out:
JSON.stringify(data, ["name"]);  // -> {"name":"Alex"}

Two habits worth keeping: never use eval to read JSON (it executes anything malicious inside), and remember that JSON.stringify silently drops functions and undefined values — if a key vanishes from your output, that's usually why.

JSON in the wild

Once you start looking, JSON is carrying data in more places than API responses:

  • Config files. package.json, tsconfig.json, and most modern tool configuration — which is where JSON's no-comments rule bites hardest, and why variants like JSONC exist.
  • JWT tokens. The authentication tokens used across the web are three Base64-encoded segments, and two of them are JSON documents. Paste one into our JWT Decoder to see the JSON payload inside, or read our JSON Web Tokens handbook for the full picture.
  • Structured data for SEO. Search engines read page metadata as JSON-LD — JSON with a vocabulary describing articles, products, and organisations. Our JSON-LD Schema Generator builds these blocks, and our technical SEO checklist covers where they fit.
  • Data exchange everywhere else. Log lines, database exports, browser localStorage — JSON is the default container for structured data that has to move between systems.

From raw JSON to working code

Formatting is usually step one of a bigger task, and two follow-up jobs come up constantly in development work:

  • Turning a payload into types. If you're consuming an API from TypeScript, our JSON to TypeScript converter generates interfaces from a sample response — paste the JSON, get the types, catch mismatches at compile time instead of runtime.
  • Generating realistic test data. When you need sample payloads to develop against before a real API exists, our Mock Data Generator produces structured JSON records with names, emails, dates, and IDs in whatever shape you define.

When JSON is the wrong tool

JSON's strictness is a feature for machine-to-machine data, but it makes JSON genuinely bad at one job: files humans edit by hand. Knowing the alternatives saves fighting the format:

FormatWhat it addsTypical use
JSONCComments allowedEditor and tool configs (VS Code uses it)
JSON5Comments, trailing commas, unquoted keysConfig files needing flexibility
YAMLIndentation-based, comments, multi-line stringsCI pipelines, infrastructure config
CSVRows and columns, opens in spreadsheetsFlat tabular data with no nesting

The rule of thumb: JSON for data programs exchange, a comment-friendly variant for files people maintain, CSV when the data is a plain table.

A few debugging habits worth adopting

  • Format API responses before reading them. Even if you're comfortable reading minified JSON, formatting surfaces structural issues faster than eyeballing it.
  • Validate before you build logic around a payload. If a field you expect is buried three levels deep in an object you didn't know existed, you want to find that before writing code that assumes otherwise.
  • Watch for type mismatches. JSON distinguishes "42" (a string) from 42 (a number) — a formatter that shows syntax highlighting makes this distinction obvious at a glance, which plain text doesn't.
  • Keep an eye on encoding. JSON strings support Unicode escape sequences (\uXXXX); if you see unexpected characters, that's usually the cause.

Frequently asked questions

Is JSON the same as a JavaScript object?
They look alike, but they're not interchangeable. A JavaScript object literal allows unquoted keys, single quotes, trailing commas, functions as values, and comments — none of which are valid JSON. JSON.stringify() and JSON.parse() are the bridge between the two.
Why does my JSON fail to parse even though it looks fine?
The most common culprits are trailing commas, single quotes, and unescaped double quotes inside a string value. A formatter with error reporting will usually catch these immediately.
Can JSON store dates?
Not natively — there's no date type in the spec. Dates are typically stored as ISO 8601 strings (e.g. "2026-02-08T10:00:00Z") and parsed into a real date object by whatever code reads them.
What is the difference between JSON and JSON5?
JSON5 is a superset of JSON designed for human-edited files — it permits comments, trailing commas, single quotes, and unquoted keys. It needs its own parser, so use it for configs where those conveniences help, and plain JSON for anything programs exchange.
Is it safe to parse JSON from an unknown source?
JSON.parse itself is safe — it only produces data, never executes code, which is exactly why it should always be used instead of eval. The care belongs one step later: validate the parsed data's shape and types before your code trusts it.
How do I handle very large JSON files?
Formatters and parsers hold the whole document in memory, so multi-hundred-megabyte files call for streaming parsers that process one record at a time. If a large file fails to open in a browser tool, that memory ceiling is usually the reason.

Put it into practice

Every guide comes with free tools to match.

Public tools open without sign-up. Local, upload, AI, and premium workspace steps are labeled clearly.

Explore all tools