JSON

On this page 7

JSON (JavaScript Object Notation) is a language-independent text format for structured data that represents values as objects, arrays, strings, numbers, booleans and null. Among data formats, it is the default choice for web APIs, configuration files and document databases because it is compact, human-readable and supported by virtually every programming language.

The format is defined by ECMA-404 and RFC 8259, which fix a deliberately small grammar. That minimalism is the source of its strengths, such as easy parsing and broad interoperability, and of its weaknesses, such as no comments, no date type and loosely specified numbers.

How JSON represents data

A JSON document is a single value, which in practice is usually an object or an array. An object is an unordered set of name and value pairs enclosed in braces, where every name is a double-quoted string. An array is an ordered list of values enclosed in brackets, and values of different types may be mixed freely.

Values nest without limit in the grammar, so a JSON document forms a tree structure. Whitespace between tokens is insignificant, which lets the same data be written as minified output for transport or pretty-printed output for people. Text exchanged between systems must be encoded as UTF-8, and strings escape control characters and quotes with a backslash.

The following table lists the six value types and the details that most often cause interoperability errors.

Value typeSyntaxPractical note
Object{“id”: 7, “name”: “Ana”}Duplicate names are allowed by the grammar but behave unpredictably
Array[1, “two”, true]Order is significant and preserved
String“text with \u00e9”Double quotes only; Unicode escapes use \u
Number-12.5e3No NaN, no Infinity, no leading zeros, no hexadecimal
Booleantrue or falseLowercase literals only
NullnullOften confused with an absent field
The six JSON value types

Parsing, numbers and precision

A JSON parser converts text into native structures, typically maps, lists and primitive values. Because the specification does not define numeric precision, most parsers map numbers to IEEE 754 double-precision floats. Integers beyond 2^53 (about 9 quadrillion) therefore lose exactness in JavaScript and in many other runtimes.

Large identifiers, monetary amounts and high-precision timestamps should therefore be transmitted as strings or handled by a parser configured for arbitrary precision. Dates have no native type, so the common convention is an ISO 8601 string such as “2026-11-09T17:40:48Z”. Binary data must be Base64-encoded, which adds roughly one third to its size.

Two parsing models dominate. A tree parser loads the whole document into memory and is simple to use, while a streaming parser emits tokens incrementally and keeps memory flat for documents of hundreds of megabytes or more.

JSON sits between verbose markup formats and binary analytical formats. It is richer than CSV because it handles nesting, simpler than XML because it has no attributes or namespaces, and far less efficient than columnar formats for large scans. The table summarizes where each format fits.

FormatStructureEncodingTypical use
JSONNested objects and arraysTextAPIs, configuration, document stores
NDJSONOne JSON value per lineTextLogs, streaming, bulk loading
CSVFlat rows and columnsTextSpreadsheets, simple exports
XMLElements, attributes, namespacesTextDocuments, legacy enterprise exchange
YAMLIndentation-based superset of JSONTextHuman-edited configuration
ParquetColumnar with typed schemaBinaryAnalytics on large datasets
Apache ArrowColumnar in-memory layoutBinaryZero-copy exchange between engines
JSON and related data formats

A practical rule is that JSON is the interchange format at the edges of a system, where readability and compatibility matter most, while Parquet or Arrow take over inside analytical pipelines where volume and scan speed dominate.

Schemas and validation

Plain JSON carries no schema, so a receiver cannot know from the syntax alone which fields are required or what types they must have. JSON Schema fills that gap with a vocabulary for declaring types, required properties, value ranges, string patterns and nested structures, and it underpins API description formats such as OpenAPI.

Validation should happen at every trust boundary: when an API receives a request, when a pipeline ingests a file and when a configuration is loaded. Schema evolution follows the usual compatibility rules, so adding optional fields is safe, while renaming or retyping fields breaks existing consumers.

Several variants extend or constrain the base format for specific needs, as the next table shows.

VariantWhat it adds or changesWhen it applies
NDJSON or JSON LinesNewline-delimited recordsAppendable logs and streaming ingestion
JSON5 and JSONCComments, trailing commasHuman-edited configuration files
JSON-LDLinked-data context and identifiersStructured metadata and knowledge graphs
GeoJSONStandard geometry objectsGeographic features and maps
BSON and CBORBinary encoding with extra typesCompact storage and constrained devices
Common JSON variants and extensions

Pitfalls and good practice

Most JSON problems arise from what the specification leaves open. The following table pairs frequent symptoms with their causes and the usual fix.

SymptomCauseFix
Identifier changes after parsingInteger above 2^53Send large IDs as strings
Parser rejects a config fileComments or trailing commasUse strict JSON or a JSON5 parser
Inconsistent field valuesDuplicate object keysReject duplicates during validation
Timestamps shift between systemsAmbiguous date stringsUse ISO 8601 with a time zone offset
Memory exhaustion on importTree parsing of huge filesUse a streaming parser or NDJSON
Code execution riskEvaluating JSON as codeAlways use a dedicated parser
Frequent JSON problems

Teams should also distinguish null from a missing field explicitly in their contracts, because many clients treat the two differently. For storage and analytics at scale, repeated field names inflate size, so compression or a conversion to a columnar format is usually worthwhile.

In plain words

JSON is a shared way of writing down information so that different programs can read it. It looks a little like a filled-in form: each piece of information has a label, such as “name” or “price”, followed by its value.

Lists go inside square brackets, and groups of labeled values go inside curly braces. Because it is plain text, a person can open it and understand it, and almost every programming language can read and write it without extra effort. That is why apps and websites use it constantly to exchange data behind the scenes.

A real-world example

A mobile banking app requests a customer’s recent transactions from its server. The server replies with a JSON object containing an array of 50 transactions, each with an identifier, an amount, a currency code and an ISO 8601 timestamp.

During testing, the team notices that some transaction identifiers change by a few digits on the client. The identifiers are 64-bit integers above 2^53, and the JavaScript parser rounds them. The team changes the contract so that identifiers and amounts are sent as strings, adds a JSON Schema that marks these fields as required strings, and validates every response in automated tests.

The outcome is a stable, precisely typed API contract: identifiers no longer drift, amounts keep their exact decimal value, and schema violations are caught before release rather than reported by customers.