| | |

JSON 01 ๐Ÿ“„ Introduction to Data Serialization and Formats

โฑ๏ธ Estimated read: 14 min | |

Data serialization is the process of converting an in-memory data structure into a format that can be stored or transmitted, and deserialization is the reverse. The format is the contract between the two sides: the writer produces the bytes, and the reader parses them back into the structure. The choice of format is not a matter of taste. It is a trade-off between human readability, machine efficiency, schema enforcement, and ecosystem support. JSON, XML, YAML, and the binary formats each sit at a different point on that trade-off, and the right choice depends on what the data is for.

JSON is the format that won the web. It is a text format with a small grammar, it is natively parseable by JavaScript, and it is the default for the HTTP APIs. The RFC 8259 defines it as a text format derived from JavaScript’s object literal syntax, and it specifies that JSON can represent four primitive typesโ€”strings, numbers, booleans, and nullโ€”and two structured typesโ€”objects and arrays . The format is not perfect: it has no comments, no built-in schema, and no support for binary data. But it is the common language that every language and every platform speaks. The alternatives exist because JSON is not the right choice for every case, and the introduction to the formats is the map of those cases.

Key point: Data serialization converts in-memory structures to storable or transmittable bytes. JSON is the text format that dominates web APIs, with UTF-8 encoding and the RFC 8259 grammar. The alternativesโ€”XML, YAML, and the binary formatsโ€”make different trade-offs between human readability, schema enforcement, and efficiency.


Why the format choice is the contract

The readability problem. A text format is readable by a human, and the readability is the debugging advantage. A JSON payload can be inspected in the browser’s network tab, a YAML configuration can be edited in a text editor, and an XML document can be validated against its schema. The binary formats are not readable, and debugging requires specialized tools. The readability is the trade-off against size and speed.

The efficiency problem. A text format is larger than the binary format that encodes the same data, and parsing is slower because the text must be tokenized and converted. A binary format like MessagePack encodes the type and length in the bytesโ€”the spec defines separate formats for nil, booleans, integers of various widths, floats, strings, and arrays, each with a distinct first byte . The parsing is a direct memory read. The efficiency is the trade-off against readability and interoperability.

The schema problem. JSON has no built-in schema, and validation is a separate layer. The JSON Schema is the standard that defines the structure, the types, and the constraints, and the current version is 2020-12, split into Core and Validation vocabularies . XML has XSD, YAML has JSON Schema or custom validators, and Protobuf has the .proto files that define the message types and field numbers . The schema is the trade-off against flexibility: a schema-enforced format is more robust, but it requires the definition and the tooling.

The security problem. JSON parsing is not inherently safe. The JSON.parse() reviver function is called for every key-value pair, and if an attacker can pollute Object.prototype with a parseReviver function through a co-dependency, every JSON response in the process can be silently modified. The Axios CVE-2026-42044 is the concrete example: a polluted parseReviver intercepted every JSON response and could escalate a role: "user" to role: "admin" or inflate a balance: 100 to balance: 999999 without any error . The security is the trade-off against the convenience of the built-in parser.

The ecosystem problem. The format is only as useful as the tools that read and write it. JSON is supported by every language and every platform, and the parsers are built into the standard libraries. YAML has good support in DevOps tooling, XML has enterprise support, and the binary formats have narrower support with the tooling as an extra dependency. The ecosystem is the trade-off against efficiency.

The interoperability problem. The RFC 8259 notes that certain patterns, while allowed by the specification, have caused interoperability problems . The large integers are the classic case: JSON allows arbitrary precision, but JavaScript’s Number is a 64-bit float, so JSON.parse("12345678901234567890") returns 12345678901234568000 because the number is rounded before the reviver is even called . The interoperability is the trade-off against the simplicity of the number model.


a. The JSON grammar and the serialization mechanics

The JSON grammar is defined by RFC 8259. A JSON text is a serialized value, and the value can be an object, an array, a string, a number, a boolean, or null. The object is an unordered collection of name/value pairs, where the name is a string and the value is any of the six types. The array is an ordered sequence of values . The strings must be double-quoted, the property names must be double-quoted, and the single quotes are not valid . The comments are not allowed, the trailing commas are not allowed, and the numbers are the decimal notation.

// The JSON grammar
const value = {
  name: "Ada",           // string (double-quoted)
  age: 36,               // number
  active: true,          // boolean
  tags: ["math", "code"], // array
  address: null,         // null
  nested: { city: "London" } // object
};

// The serialization
const json = JSON.stringify(value);
// '{"name":"Ada","age":36,"active":true,"tags":["math","code"],"address":null,"nested":{"city":"London"}}'

// The deserialization
const parsed = JSON.parse(json);
// { name: 'Ada', age: 36, active: true, ... }

The JSON.stringify() method accepts three parameters: the value, an optional replacer that can filter or transform the properties, and an optional space that adds the indentation for readability. The replacer can be a function that receives each key and value, or an array of the property names to include . The toJSON() method on an object is called by JSON.stringify() before the serialization, which is the mechanism that the Date object uses to serialize as an ISO string.

// The replacer and the space
const json = JSON.stringify(value, (key, val) => {
  // The function is called for every key-value pair.
  // Returning undefined omits the property.
  if (key === "password") return undefined;
  return val;
}, 2); // The 2-space indentation

// The toJSON method
const date = new Date("2026-01-01");
JSON.stringify(date); // '"2026-01-01T00:00:00.000Z"'

The JSON.parse() method accepts the text and an optional reviver function. The reviver is called for every key-value pair, bottom-up, and the return value replaces the value in the result . The reviver is the mechanism that the Axios vulnerability exploited: the polluted Object.prototype.parseReviver was inherited by the config object, and the JSON.parse(data, this.parseReviver) call invoked it for every response .

// The reviver
const parsed = JSON.parse('{"a":1,"b":2}', (key, val) => {
  if (key === "b") return val * 10;
  return val;
});
// { a: 1, b: 20 }

b. The variants and the binary formats

The JSON variants extend the grammar for specific use cases. JSON5 allows comments, single quotes, unquoted names, hexadecimal numbers, and trailing commas. It is the “JSON for Humans” . JSONC is the JSON with comments and trailing commas, and it is the format that VS Code accepts. JSON Lines (NDJSON) is the format where each line is a separate JSON document, and it is the format for streaming and line-oriented processing. The NDJSON specification requires each line to be a valid JSON value, and the FHIR specification uses it for bulk data transfer with the MIME type application/fhir+ndjson .

The binary formats are the efficiency alternatives. MessagePack encodes the same data model as JSON, with a compact binary representation: the nil is 0xc0, the booleans are 0xc2 and 0xc3, the integers have separate formats for 8, 16, 32, and 64 bits, and the strings and arrays have length prefixes . The IANA registered application/vnd.msgpack in 2024 . Protobuf is the schema-driven binary format, and the .proto files define the message types, the field numbers, and the wire format. The field numbers are limited to 29 bits because three bits are used for the wire type, and the reusing a field number is a serious mistake . BSON is the binary format that MongoDB uses, and the specification defines the document as an int32 length followed by the elements and a null terminator .

// The JSON Lines format
// Each line is a separate JSON document.
const ndjson = '{"name":"Ada"}\n{"name":"Grace"}\n{"name":"Linus"}\n';

// The parsing
const records = ndjson.trim().split('\n').map(line => JSON.parse(line));
// [{ name: 'Ada' }, { name: 'Grace' }, { name: 'Linus' }]

The JSON Schema is the validation layer. The 2020-12 specification defines the Core and the Validation vocabularies, and the meta-schema that validates the schemas themselves . The $schema keyword declares the version, the $id declares the base URI, the type declares the type, the properties declares the object properties, and the required declares the required properties. The $ref is the mechanism that references another schema, and the unevaluatedProperties is the mechanism that guards against the misspelled properties .

// The JSON Schema
const schema = {
  $schema: "https://json-schema.org/draft/2020-12/schema",
  type: "object",
  properties: {
    name: { type: "string" },
    age: { type: "integer", minimum: 0 },
  },
  required: ["name"],
  unevaluatedProperties: false,
};

Complete Example Session

// ============================================
// PART 1: THE JSON GRAMMAR
// ============================================

// The six value types: object, array, string, number, boolean, null.
const value = {
  name: "Ada",
  age: 36,
  active: true,
  tags: ["math", "code"],
  address: null,
};

// The strings and the property names must be double-quoted.
// The single quotes and the comments are not valid.

// ============================================
// PART 2: THE SERIALIZATION
// ============================================

const json = JSON.stringify(value);
// '{"name":"Ada","age":36,"active":true,"tags":["math","code"],"address":null}'

// The replacer filters the properties.
const filtered = JSON.stringify(value, (key, val) => {
  if (key === "address") return undefined;
  return val;
});

// The space adds the indentation.
const pretty = JSON.stringify(value, null, 2);

// ============================================
// PART 3: THE DESERIALIZATION
// ============================================

const parsed = JSON.parse(json);

// The reviver transforms the values.
const transformed = JSON.parse('{"a":1,"b":2}', (key, val) => {
  if (key === "b") return val * 10;
  return val;
});

// ============================================
// PART 4: THE LARGE INTEGER PROBLEM
// ============================================

// JSON allows arbitrary precision, but JavaScript does not.
const big = JSON.parse("12345678901234567890");
// 12345678901234568000 (rounded)

// The fix: serialize the number as a string.
const safe = JSON.stringify({ big: "12345678901234567890" });

// ============================================
// PART 5: THE PROTOYPE POLLUTION RISK
// ============================================

// The polluted parseReviver is called for every JSON response.
Object.prototype.parseReviver = (key, val) => {
  if (key === "role") return "admin";
  return val;
};

const response = JSON.parse('{"role":"user","balance":100}');
// { role: 'admin', balance: 100 } (the role was escalated)

delete Object.prototype.parseReviver;

// ============================================
// PART 6: THE JSON LINES
// ============================================

const ndjson = '{"name":"Ada"}\n{"name":"Grace"}\n';
const records = ndjson.trim().split('\n').map(line => JSON.parse(line));

// ============================================
// PART 7: THE JSON SCHEMA
// ============================================

const schema = {
  $schema: "https://json-schema.org/draft/2020-12/schema",
  type: "object",
  properties: { name: { type: "string" } },
  required: ["name"],
};

// ============================================
// PART 8: THE MESSAGEPACK
// ============================================

// The nil: 0xc0
// The true: 0xc3
// The false: 0xc2
// The int: 0xcc (uint8), 0xcd (uint16), etc.

// ============================================
// PART 9: THE PROTOBUF
// ============================================

// The message definition:
// message SearchRequest {
//   string query = 1;
//   int32 page_number = 2;
// }

// The field numbers are the wire identifiers.

// ============================================
// PART 10: THE CHECKLIST
// ============================================

// [ ] The JSON is the default for the APIs.
// [ ] The JSON5 or JSONC is used for the config files with comments.
// [ ] The JSON Lines is used for the streaming.
// [ ] The large integers are serialized as strings.
// [ ] The reviver is not polluted.
// [ ] The JSON Schema is used for the validation.
// [ ] The binary format is used for the high-performance cases.

The ten parts covered the grammar, the serialization, the deserialization, the large integer problem, the prototype pollution risk, the JSON Lines, the JSON Schema, the MessagePack, the Protobuf, and the checklist. The through-line is that the format is the contract, and the choice is the trade-off.


Quick Reference

The text formats

FormatReadabilitySchemaCommentsUse case
JSONHighExternal (JSON Schema)NoWeb APIs, data storage
XMLMediumXSDYesEnterprise, document-centric
YAMLHighExternal (JSON Schema)YesConfiguration, DevOps
JSON5HighExternalYesHuman-edited config
JSONCHighExternalYesVS Code config
JSON LinesHighExternalNoStreaming, line-oriented

The binary formats

FormatSchemaSizeUse case
MessagePackNoSmallBinary JSON
ProtobufYes (.proto)SmallgRPC, high-performance
BSONNoMediumMongoDB

The JSON Schema

VersionStatus
2020-12Current
2019-09Previous

The serialization edge cases

CaseBehavior
undefinedOmitted from the output
NaN / InfinityConverted to null
BigIntThrows a TypeError
Circular referenceThrows a TypeError
DateSerialized via toJSON()
Large integerRounded to the nearest float

Best Practices

โœ… Do This:

// Use JSON for the web APIs
const payload = JSON.stringify(data);

// Use JSON5 or JSONC for the config files with comments
// Use YAML for the human-edited config
// Use JSON Lines for the streaming

// Serialize the large integers as strings
const safe = JSON.stringify({ big: "12345678901234567890" });

// Validate the JSON Schema
const valid = validate(schema, data);

โŒ Don’t Do This:

// Use eval() to parse JSON
const data = eval('(' + json + ')'); // the security risk

// Trust the reviver from the prototype chain
JSON.parse(data, this.parseReviver); // the Axios CVE 

// Assume the large integers are exact
JSON.parse("12345678901234567890"); // rounded

Common Pitfalls

PitfallWhy It HappensFix
The JSON parse failsThe trailing comma or the single quoteUse a strict JSON parser
The large integer is wrongJavaScript’s float precisionSerialize as a string
The prototype is pollutedThe reviver is inherited from the prototype chainValidate the reviver is an own property
The schema is not validatedThe JSON Schema is not appliedAdd the schema validation
The binary format is not readableThe format is not textUse the tooling to inspect

Real-World Examples

1. The basic serialization

JSON.stringify({ name: "Ada", age: 36 });
// '{"name":"Ada","age":36}'

2. The pretty-print

JSON.stringify({ name: "Ada" }, null, 2);
// '{\n  "name": "Ada"\n}'

3. The replacer

JSON.stringify({ name: "Ada", password: "x" }, (k, v) => k === "password" ? undefined : v);
// '{"name":"Ada"}'

4. The reviver

JSON.parse('{"a":1}', (k, v) => k === "a" ? v * 2 : v);
// { a: 2 }

5. The large integer as a string

JSON.stringify({ big: "12345678901234567890" });
// '{"big":"12345678901234567890"}'

6. The JSON Lines

'{"a":1}\n{"b":2}\n'.trim().split('\n').map(JSON.parse);
// [{ a: 1 }, { b: 2 }]

7. The JSON Schema

{ $schema: "https://json-schema.org/draft/2020-12/schema", type: "object" };

8. The MessagePack nil

// The nil is the single byte 0xc0

9. The Protobuf field number

// message SearchRequest { string query = 1; }

10. The BSON document

// The document is the int32 length + the elements + the null byte

Visual

The Serialization Contract

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE FORMAT IS THE CONTRACT                                  โ”‚
โ”‚                                                              โ”‚
โ”‚  In-memory structure                                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                    โ”‚
โ”‚  โ”‚ { name: "Ada",      โ”‚                                    โ”‚
โ”‚  โ”‚   age: 36 }         โ”‚                                    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                    โ”‚
โ”‚             โ”‚                                                โ”‚
โ”‚             โ”‚ serialize                                      โ”‚
โ”‚             โ–ผ                                                โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                    โ”‚
โ”‚  โ”‚ '{"name":"Ada",     โ”‚  The bytes                         โ”‚
โ”‚  โ”‚   "age":36}'        โ”‚                                    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                    โ”‚
โ”‚             โ”‚                                                โ”‚
โ”‚             โ”‚ deserialize                                    โ”‚
โ”‚             โ–ผ                                                โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                    โ”‚
โ”‚  โ”‚ { name: "Ada",      โ”‚  The structure                     โ”‚
โ”‚  โ”‚   age: 36 }         โ”‚                                    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The JSON Types

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THE SIX VALUE TYPES                                         โ”‚
โ”‚                                                              โ”‚
โ”‚  Primitive:                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”‚
โ”‚  โ”‚ string      โ”‚  โ”‚ number      โ”‚  โ”‚ boolean     โ”‚         โ”‚
โ”‚  โ”‚ "text"      โ”‚  โ”‚ 42, 3.14    โ”‚  โ”‚ true/false  โ”‚         โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                            โ”‚
โ”‚  โ”‚ null        โ”‚                                            โ”‚
โ”‚  โ”‚ null        โ”‚                                            โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                            โ”‚
โ”‚                                                              โ”‚
โ”‚  Structured:                                                 โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                          โ”‚
โ”‚  โ”‚ object      โ”‚  โ”‚ array       โ”‚                          โ”‚
โ”‚  โ”‚ {"key":val} โ”‚  โ”‚ [val, val]  โ”‚                          โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Binary Format Comparison

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  TEXT VS BINARY                                              โ”‚
โ”‚                                                              โ”‚
โ”‚  JSON (text)                 MessagePack (binary)           โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”‚
โ”‚  โ”‚ {"a":1}             โ”‚     โ”‚ 0x81 0xa1 0x61 0x01 โ”‚        โ”‚
โ”‚  โ”‚                     โ”‚     โ”‚                     โ”‚        โ”‚
โ”‚  โ”‚ 7 bytes             โ”‚     โ”‚ 4 bytes             โ”‚        โ”‚
โ”‚  โ”‚ Readable            โ”‚     โ”‚ Not readable        โ”‚        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ”‚
โ”‚                                                              โ”‚
โ”‚  The binary format is smaller and faster to parse.          โ”‚
โ”‚  The text format is readable and universally supported.     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
JSONThe text format, RFC 8259, UTF-8
XMLThe markup format, schema support
YAMLThe indentation format, comments, JSON superset
JSON5The JSON for humans, comments, single quotes
JSONCThe JSON with comments, VS Code format
JSON LinesThe line-oriented JSON, streaming
MessagePackThe binary JSON, compact encoding
ProtobufThe schema-driven binary, field numbers
BSONThe MongoDB binary, length-prefixed
JSON SchemaThe validation, 2020-12

Key takeaways:

  • Serialization is the contract between the writer and the reader. The format is the trade-off between human readability, machine efficiency, schema enforcement, and ecosystem support. The choice depends on what the data is for, not on what is fashionable.
  • JSON is the default for the web APIs. The RFC 8259 defines the six value typesโ€”four primitives and two structuredโ€”and the UTF-8 encoding . The format has no comments and no built-in schema, and the JSON Schema is the separate validation layer .
  • The JSON variants extend the grammar for specific cases. JSON5 and JSONC add the comments for the config files . JSON Lines (NDJSON) is the line-oriented format for streaming, and it is used by FHIR for bulk data transfer .
  • The binary formats are the efficiency alternative. MessagePack encodes the same data model with a compact byte format, and the IANA registered the media type in 2024 . Protobuf is the schema-driven format with the field numbers, and BSON is the MongoDB format with the length-prefixed documents .
  • The security and the interoperability are the real risks. The prototype pollution of the reviver function can silently modify every JSON response, and the Axios CVE-2026-42044 is the concrete example . The large integers are rounded by JavaScript’s float precision before the reviver is even called .

Remember: Data serialization is the conversion of the in-memory structures to the bytes that can be stored or transmitted. JSON is the text format that the web speaks, and the RFC 8259 is the grammar. The alternatives exist because JSON is not the right choice for every case: XML for the schema-heavy enterprise, YAML for the human-edited configuration, the binary formats for the efficiency. The format is the contract, and the choice is the trade-off. The security and the interoperability are the costs that the choice must account for.

Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!