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.

Rakesh P R

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.

JSON versus a JavaScript object

This is the single most common source of "but it looked fine" JSON. Every JSON document is valid JavaScript, but the reverse is emphatically not true. A JavaScript object literal may use unquoted keys, single quotes, trailing commas, comments, functions, and the values NaN, Infinity, and undefined. JSON allows none of these. Keys must be double-quoted strings, strings must use double quotes, and the only permitted values are objects, arrays, strings, numbers, true, false, and null.

So this is a perfectly good JavaScript object and an invalid JSON document:

{ // the current user name: 'Leanne', scores: [90, 95,], lastSeen: undefined }

The JSON version quotes the keys and the string, drops the comment and the trailing comma, and replaces undefined with null:

{ "name": "Leanne", "scores": [90, 95], "lastSeen": null }

Common parser errors and what they mean

Trailing comma. A comma before a closing } or ] is legal in modern JavaScript and never legal in JSON. Parsers report it at the closing brace, one character after the real mistake.

Single-quoted string. JSON has exactly one string delimiter: the double quote. A parser stops at the opening quote character it did not expect.

Unquoted key. Every key is a double-quoted string, so a bare identifier fails where the parser expected a quote.

Comments. JSON has no comment syntax. Strip // and /* */ before parsing, or move the note into a real field.

NaN, Infinity, undefined. These are JavaScript values with no JSON equivalent. Use null, or a string, or omit the field.

Unterminated string. A missing closing quote, or a literal newline inside a string. Line breaks inside a JSON string must be escaped as \n.

Because these mistakes are reported at the point the parser gave up rather than the point you made the error, the reported position is usually just after the real problem. A formatter that shows the line, column, and surrounding excerpt is what turns that into a two-second fix.

Validating shape with JSON Schema

Valid syntax only tells you the document parses. It says nothing about whether the data is the shape your code expects — a response can be perfect JSON and still be missing the id your code reads. JSON Schema is the standard vocabulary for describing that shape.

A minimal workflow:

  1. Start from a real response. Note which fields your code actually depends on.
  2. Write the smallest useful schema — the type of the root, the required fields, and the type of each one.
  3. Validate a known-good document against it and confirm it passes.
  4. Validate a known-bad document — delete a required field, change a type — and confirm it fails where you expect.
  5. Tighten only as far as you need. An over-specified schema breaks on harmless additions.

For example, this schema requires an object with an integer id of at least 1 and a name of at least two characters:

{ "type": "object", "required": ["id", "name"], "properties": { "id": { "type": "integer", "minimum": 1 }, "name": { "type": "string", "minLength": 2 } } }

The JSON Formatter's Schema view runs exactly this kind of check in your browser and reports the path of each failure. It implements a subset of the specification and tells you when a schema uses a keyword it does not support, so an unsupported schema is never mistaken for a passing one.

The JSON standard, and where to check it

JSON is defined by two documents that agree with each other: ECMA-404, The JSON Data Interchange Syntax, and IETF RFC 8259, which supersedes the earlier RFC 7159 and RFC 4627. Both are short and readable, and either settles an argument about what is legal.

  • ECMA-404: https://ecma-international.org/publications-and-standards/standards/ecma-404/
  • RFC 8259: https://www.rfc-editor.org/rfc/rfc8259
  • JSON Schema: https://json-schema.org/specification
  • MDN on JSON.parse: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

Two useful details that surprise people: JSON has no integer type — every number is a double, so very large integers lose precision — and object key order carries no meaning in the specification, even though every common parser preserves it.

Where to go next

Once the JSON is valid, the usual next step is turning it into something your code can use. If you are working in TypeScript, the JSON-to-TypeScript tool generates interfaces from a sample document: /tools/json-to-ts

If the data belongs in a spreadsheet, or arrived as one, the CSV-to-JSON converter handles both directions with row-level diagnostics: /tools/csv-json-converter

Sources and review

How this article was checked

Standard: RFC 8259 / STD 90, ECMA-404 2nd edition

Boundaries. Formatting is not schema validation: well-formed JSON can still be semantically wrong for its consumer. Very large documents are limited by browser memory. Key order is preserved but is not significant in JSON. Numbers round-trip through IEEE-754 doubles, so integers beyond 2^53 lose precision.

Primary sources

Written by Rakesh P R. Reviewed by Rakesh P R on . Next review due . Motifuse is operated by one person, so this is the author's own review against the primary sources listed above — not an independent or peer review.

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