8 min read

JSON vs YAML: Differences, Use Cases and How to Convert

JSON vs YAML compared on syntax, comments, types, safety and token cost. YAML 1.2 is a strict superset of JSON. When to use each and how to convert both ways.

By json2toon.co

JSON is a strict, minimal data-interchange format built for machines and APIs. YAML is a human-friendly superset of JSON (as of YAML 1.2) that adds comments, anchors and multi-line strings, and that is what makes it popular for config files. Use JSON for data exchange and YAML for files people edit by hand. Convert between them with the JSON to YAML converter.

What are the main differences between JSON and YAML?

AspectJSONYAML
SpecRFC 8259 (2017)YAML 1.2.2 (2021)
StructureBraces, brackets, quotesIndentation, dashes
CommentsNone# comments
StringsAlways double-quotedUsually unquoted, which leads to type guessing
Duplicate keysNames "SHOULD be unique"; JS keeps the lastError in js-yaml
ReuseNoneAnchors & and aliases *
Parser safetyData onlySome parsers support language-specific tags; use safe loaders
Avg. tokens (TOON benchmark)4,308 (pretty), 2,892 (compact)3,487
Typical useAPIs, logs, data exchangeKubernetes, CI pipelines, app config

Sources: RFC 8259, YAML 1.2.2, and the TOON benchmark. Parser behavior comes from our own tests with js-yaml 5.4.2 and PyYAML 6.0.3.

What does the same data look like in each?

{
  "service": "billing-api",
  "version": "2.4.1",
  "replicas": 3,
  "debug": false,
  "ports": [
    8080,
    9090
  ],
  "database": {
    "host": "db.internal",
    "port": 5432,
    "pool": {
      "min": 2,
      "max": 10
    }
  }
}

The same config as YAML, from yaml.dump() in js-yaml 5:

service: billing-api
version: 2.4.1
replicas: 3
debug: false
ports:
  - 8080
  - 9090
database:
  host: db.internal
  port: 5432
  pool:
    min: 2
    max: 10

YAML drops the braces and most of the quotes. That is why people find it easier to read, and also why its type rules are trickier.

Is YAML really a superset of JSON?

Yes. The YAML 1.2 spec says its "primary focus was making YAML a strict superset of JSON". js-yaml parses {"a": [1, 2, {"b": null}], "c": "x"} to exactly the same value as JSON.parse. So any YAML 1.2 tool can read your JSON files as they are. The reverse doesn't hold.

Which YAML type rules catch people out?

Unquoted scalars are guessed, and the guess depends on which YAML version the parser follows. Here is the same input loaded two ways:

country: NO
enabled: yes
octal: 0755
zip: 01234

# js-yaml 5 default (YAML 1.2 core schema)
{"country":"NO","enabled":"yes","octal":755,"zip":1234}

# js-yaml 5 with YAML11_SCHEMA (same rules as PyYAML)
{"country":false,"enabled":true,"octal":493,"zip":668}

PyYAML 6's safe_load also turned country: NO into false in our test. This is the well-known "Norway problem". Even the 1.2 parser drops the leading zero from 01234. The fix is simple: quote any string that looks like a number, boolean or date. js-yaml's dumper already does this. It writes country: 'NO', version: '1.10' and zip: '01234'.

Two more differences. JavaScript's JSON.parse('{"a":1,"a":2}') silently keeps 2, while js-yaml throws "duplicated mapping key". And merge keys (<<: *base) are a YAML 1.1 feature: js-yaml 5's default schema keeps << as a literal key and does not merge.

Is YAML safe to parse?

YAML supports tags, and some parsers map tags to language objects, so loading untrusted YAML with a full loader has historically been risky. Use safe loaders: yaml.safe_load in Python, and js-yaml 5's default load, which rejects !!js/function with "unknown scalar tag". JSON parsers only ever produce plain data.

How do you convert JSON to YAML and back?

For one-off conversions, use JSON to YAML or YAML to JSON. Both run in your browser on js-yaml. In code:

// Node.js, js-yaml 5 (no default export)
import * as yaml from "js-yaml";

const data = yaml.load(yamlText);            // YAML -> JS value
const json = JSON.stringify(data, null, 2);  // -> JSON
const back = yaml.dump(JSON.parse(json), { lineWidth: -1 }); // JSON -> YAML
# Python, PyYAML
import json, yaml

with open("config.yaml", encoding="utf-8") as f:
    data = yaml.safe_load(f)
print(json.dumps(data, indent=2))
print(yaml.safe_dump(data, sort_keys=False))

Converting loses information. Comments are dropped, anchors are expanded into copies, and with a YAML 1.1 parser, unquoted values like NO may change type. Keep the YAML file as the source of truth if people edit it.

Which is better for LLM prompts?

In the official TOON benchmark (spec v4.1, 5,856 calls), YAML averaged 3,487 tokens at 70.1% accuracy. Pretty-printed JSON averaged 4,308 tokens at 71.4%, compact JSON 2,892 at 69.0%, and TOON 2,474 at 72.2%. TOON used 42.6% fewer tokens than JSON overall. The accuracy intervals overlap, so the token count is the real difference. YAML beats pretty JSON but loses to minified JSON. For the same config as TOON, see YAML vs TOON, and for the minified comparison, TOON vs minified JSON.

When should you use JSON, and when YAML?

  • Use JSON for APIs, data exchange between services, logs, and anything generated and parsed by machines. Every language has a fast, strict parser for it.
  • Use YAML for config that people edit and review: deployment manifests, CI workflows, app settings. Comments are worth the type-guessing risk there.
  • Avoid YAML for untrusted input or large data payloads. For tabular data, see how to convert JSON to CSV.

Frequently Asked Questions

Is YAML a superset of JSON?

Yes, since YAML 1.2, whose primary focus was making YAML a strict superset of JSON. In practice almost any JSON document parses as YAML with the same result. The reverse is not true: comments, anchors and unquoted strings are YAML-only and are lost or rejected when converting to JSON.

What is the Norway problem in YAML?

YAML 1.1 parsers read unquoted values like NO, yes and on as booleans, so a country code NO becomes false. PyYAML 6 still does this. YAML 1.2 parsers such as js-yaml 5 keep NO as a string. Quoting such values avoids the problem in every parser.

Does converting YAML to JSON keep comments?

No. JSON has no comment syntax, so comments are dropped when YAML is parsed into data. Anchors and aliases are expanded into copies. If you need to round-trip a hand-edited config, keep YAML as the source of truth and generate JSON from it.

Is YAML or JSON cheaper in LLM prompts?

YAML is cheaper than pretty-printed JSON but more expensive than minified JSON. In the official TOON benchmark, YAML averaged 3,487 tokens, JSON 4,308 and compact JSON 2,892, with overlapping accuracy. TOON averaged 2,474 tokens on the same questions.

Recommended Reading

JSONYAMLComparisonConfigurationData FormatConversion