Skip to content
Developer 10 min · Jan 30, 2025

Understanding JSON: A Practical Guide for Developers

RFC 8259 syntax, validation, common pitfalls, and best practices for working with JSON.

H
HT99 Tools Editorial Team
Editorial Team

What JSON Is, per RFC 8259

JSON (JavaScript Object Notation) is a lightweight, text-based data interchange format formally specified in RFC 8259 (T. Bray, ed., December 2017), which is also designated Internet STD 90. Despite the name, JSON is not JavaScript; it is a strict subset of JavaScript syntax whose parsing rules are defined by the RFC, not by the ECMAScript specification. A JSON document is "a sequence of tokens" formed from Unicode code points, with six structural characters, three literal keywords, and four primitive value types. The format succeeded XML for most web APIs because it is dramatically less verbose, parses in a single pass, and maps directly onto the native data structures of virtually every modern programming language.

The six structural characters are { } [ ] : ,. The three literal keywords are true, false, and null, all lowercase. The four primitive types are string, number, boolean, and null. Composed on top of these are the two container types: objects (an unordered collection of name/value pairs enclosed in { }) and arrays (an ordered collection of values enclosed in [ ]). RFC 8259 requires that JSON text be encoded in UTF-8 — earlier drafts allowed UTF-16 and UTF-32, but STD 90 mandates UTF-8 because it is universally interoperable.

JSON Syntax Rules

A JSON object is enclosed in curly braces, with each name/value pair separated by a colon and consecutive pairs separated by a comma. Names must be strings wrapped in double quotes — single quotes are not allowed. Values can be strings, numbers, the literals true, false, null, objects, or arrays. Strings themselves use double quotes and support the standard escape sequences: \\", \\\\, \\/, \\b, \\f, \\n, \\r, \\t, and \\uXXXX for any Unicode code point.

{
  "name": "Ada Lovelace",
  "born": 1815,
  "fields": ["mathematics", "analytical engine"],
  "notes": null,
  "verified": true
}

Numbers in JSON follow a syntax close to but not identical to most programming languages' numeric literals. They can be integers, fractions with a single decimal point, or use exponent notation with e or E. They cannot have leading zeros (so 007 is invalid), cannot begin or end with a decimal point (so .5 and 5. are both invalid), cannot use a plus sign in the exponent's sign (so 1e+5 is valid but 1e++5 is not), and cannot be NaN or Infinity — those values are not part of the JSON specification. RFC 8259 does not specify numeric precision, which means very large integers can lose precision when parsed by JavaScript's JSON.parse because JavaScript stores all numbers as IEEE 754 double-precision floats.

Common Pitfalls

  • Trailing commas. {"a": 1, "b": 2,} is invalid JSON. JavaScript object literals allow trailing commas in modern engines, which is why this error slips through manual testing and only surfaces when the data crosses a language boundary.
  • Single-quoted strings. {'a': 1} is invalid JSON. JSON requires double quotes on both keys and string values.
  • Comments. // comment and /* comment */ are not part of JSON. Several configuration-file formats (JSON5, JSONC, VS Code's settings.json) extend JSON with comments, but these extensions are not interoperable and will fail strict parsers such as Python's json.loads.
  • Unquoted keys. {name: "Ada"} is valid JavaScript but invalid JSON. JSON requires every key to be a double-quoted string.
  • NaN and Infinity. These are not part of the JSON specification. JavaScript's JSON.stringify converts them to null by default, which silently loses information.
  • Integer precision. Integers above 2^53 lose precision when parsed by JavaScript because JavaScript's Number type is an IEEE 754 double. For identifiers like Twitter snowflake IDs or Stripe charge IDs, transmit them as strings, not numbers.
  • Duplicate keys. RFC 8259 says the behavior of parsers receiving duplicate names is "implementation-defined." Most parsers keep the last value, but relying on this is asking for trouble. Use unique keys.

Validation and Schema

Syntax validation tells you whether a JSON document is well-formed. Semantic validation — whether the values are the right types, in the right ranges, with the right required fields — is the job of JSON Schema (currently a draft at json-schema.org, widely implemented). A schema document is itself JSON; it specifies required properties, types, formats (email, uri, date-time), numeric ranges, string patterns, and array constraints. Server-side validation with a JSON Schema library is a low-cost way to catch malformed API requests before they reach business logic.

{
  "\$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["name", "born"],
  "properties": {
    "name": {"type": "string", "minLength": 1},
    "born": {"type": "integer", "minimum": 1800, "maximum": 2100}
  }
}

Parsing and Serializing Safely

In JavaScript, use JSON.parse(text, reviver) and JSON.stringify(value, replacer, space). Never use eval() on JSON text — JSON is a strict subset of JavaScript precisely so that safe parsers can exist, and eval would execute arbitrary code if the input were ever tampered with. In Python, json.loads and json.dumps are the standard pair; pass parse_float=decimal.Decimal if you need exact decimal arithmetic for financial data, because Python's default float parsing also uses IEEE 754 doubles.

When serializing, control whitespace deliberately. JSON.stringify(value, null, 2) produces 2-space indented output that is readable for humans but roughly 20 to 30 percent larger than the minified form. For API responses served over the network, minify by default and offer pretty-printing only behind a query parameter for debugging. For configuration files checked into version control, pretty-print for diff readability.

Representing Dates and Binary Data

JSON has no native date type. The two conventional patterns are ISO 8601 strings ("2025-03-15T14:30:00Z") and Unix timestamps as numbers (1742041800). ISO 8601 is human-readable, sortable as a string, and unambiguous when it includes a timezone offset or a trailing Z; Unix timestamps are compact and timezone-agnostic but unreadable without conversion. Pick one convention per API and apply it uniformly; mixing the two is a recurring source of off-by-hours bugs.

Binary data has no native representation either. Small blobs (cryptographic hashes, certificates, opaque tokens) are usually base64-encoded into a string field per RFC 4648. Large blobs should not be embedded in JSON at all — upload them separately and reference by URL, because a 50 MB image embedded as a base64 string in a JSON body becomes a 67 MB string that must be parsed atomically by every consumer.

Performance and Size Considerations

JSON is verbose compared to binary formats like Protocol Buffers or MessagePack, but it is human-readable, debuggable with any text editor, and natively parsed by every modern programming language. For most web APIs the bandwidth cost is dwarfed by TLS handshake and network latency, and the developer-time savings of a debuggable format more than compensate. When payload size does matter — high-frequency telemetry, mobile clients on metered connections — consider gzip compression first; JSON compresses extremely well because of its repetitive structural characters, often to under 10 percent of its uncompressed size. Binary formats are a last resort, not a first optimization.

Conclusion

JSON's simplicity is its strength. Six structural characters, three literal keywords, four primitive types, two container types, and a one-page specification are all you need to remember. The pitfalls are well-known and almost all stem from confusing JSON with JavaScript: trailing commas, single quotes, comments, unquoted keys, and the silent loss of large integers to IEEE 754 doubles. Validate on the boundary with JSON Schema, parse with the standard library, never eval, and transmit large numeric identifiers as strings. JSON is not going to be replaced in our lifetimes; learning to use it correctly is a one-time investment that pays off on every API you build. Written by the HT99 Tools Editorial Team.

Try the Tool This Article Explains

Put what you've learned into practice with our free, accurate calculators.

Browse All Tools → More Articles