About YAML / JSON / XML
YAML 1.2 is a strict superset of JSON, so every JSON document is already valid YAML and conversion in that direction is really a reformat. Going the other way is where information is lost, because YAML has features JSON simply cannot express.
Three of those matter in practice. Comments are the obvious one - JSON has no comment syntax, so converting a Kubernetes manifest or CI pipeline to JSON and back silently deletes every explanatory line in it. Anchors and aliases (&name and *name) let YAML reuse a block by reference, and JSON has to expand them, which inflates the document and loses the intent. And a single YAML file can hold multiple documents separated by ---, where JSON permits exactly one.
The other direction has its own hazard: YAML's implicit typing. In YAML 1.1, which PyYAML and Go's yaml.v2 still follow, the unquoted words yes, no, on, off, y and n parse as booleans - so a country code of NO becomes false and a key named on becomes true. Unquoted 1.10 becomes the float 1.1, losing a digit, and a value like 22:30 can parse as a base-60 integer. This cluster of surprises is known as the Norway problem.
The practical rule is to quote anything in YAML that could be read as something else: version strings, country codes, file modes with leading zeros, and anything containing a colon. YAML 1.2 narrowed the boolean set to true/false, but you cannot assume the parser on the other end implements 1.2.
Conversion runs in your browser and nothing is transmitted.
How to use the YAML / JSON / XML
- Paste YAML or JSON - the direction is detected from the input.
- If you are converting YAML to JSON, note that comments and anchors will not survive.
- If you are converting JSON to YAML, quote any value that could be misread - versions, country codes, leading-zero numbers.
- For multi-document YAML, handle each document separately; JSON cannot hold more than one.
Examples
-
YAML
name: UUID Studio version: 1
YAML / JSON / XML in code
The same operation this tool performs, in the languages you are most likely to need it.
# YAML -> JSON
yq -o json '.' file.yaml
python3 -c "import yaml,json,sys; print(json.dumps(yaml.safe_load(open(sys.argv[1])), indent=2))" file.yaml
# JSON -> YAML
yq -P '.' file.json
python3 -c "import yaml,json,sys; print(yaml.safe_dump(json.load(open(sys.argv[1])), sort_keys=False))" file.json
# Multi-document YAML: yq handles each with -s, JSON cannot
yq -o json -s '.' multi.yaml
import yaml, json
# ALWAYS safe_load. yaml.load() can construct arbitrary Python
# objects and is a remote code execution risk on untrusted input.
data = yaml.safe_load(raw)
# Dumping: default_flow_style=False gives block style,
# sort_keys=False preserves your ordering
print(yaml.safe_dump(data, default_flow_style=False,
sort_keys=False, allow_unicode=True))
# Multiple documents
for doc in yaml.safe_load_all(raw):
print(json.dumps(doc))
# The Norway problem, demonstrated
yaml.safe_load("country: NO") # {'country': False} in YAML 1.1
yaml.safe_load('country: "NO"') # {'country': 'NO'} quoted - correct
yaml.safe_load("version: 1.10") # {'version': 1.1} digit lost
import YAML from "yaml"; // the "yaml" package implements 1.2
const data = YAML.parse(yamlText);
const out = YAML.stringify(jsonData);
// js-yaml follows 1.1 more closely, so the boolean surprises apply:
// YAML.parse("a: no") -> { a: false } in js-yaml
// Check which spec version your library implements before relying
// on unquoted values.
// Multiple documents
for (const doc of YAML.parseAllDocuments(yamlText)) {
console.log(doc.toJSON());
}
When you need this
- Converting a Kubernetes manifest to JSON to feed it to a tool or an API.
- Turning a JSON config into YAML so a human can read and comment on it.
- Checking how YAML's implicit typing interpreted a value.
- Splitting a multi-document YAML file into individual JSON objects.
Common problems and what causes them
- The Norway problem: unquoted NO becomes false
- YAML 1.1 treats yes, no, on, off, y and n as booleans, and PyYAML and Go's yaml.v2 still do. A country code of NO, a key called on, or an answer of y all change type. Quote anything that could be read as a boolean.
- Version numbers losing a digit
- Unquoted 1.10 is a float and becomes 1.1; 1.20 becomes 1.2. Always quote version strings.
- Comments deleted by a round trip
- JSON has no comments, so YAML to JSON and back removes all of them, plus anchors, aliases and original formatting. Never round-trip a config file you care about.
- yaml.load() as a code execution risk
- Python's yaml.load without a safe loader can instantiate arbitrary objects from YAML tags, making it a remote code execution vector on untrusted input. Use yaml.safe_load, always.
- Tabs used for indentation
- YAML forbids tabs as indentation, and the resulting error is usually unhelpful about the cause. Use spaces.
- Multiple documents in one file
- A --- separated YAML file holds several documents. JSON holds exactly one, so a converter must either take the first, produce an array, or emit several outputs - check which yours does.
FAQ
- Is JSON valid YAML?
- Yes - YAML 1.2 is a strict superset of JSON, so a YAML parser can read any JSON document. The reverse is not true, because YAML has comments, anchors, multiple documents and multi-line scalars with no JSON equivalent.
- Why did my YAML value NO become false?
- YAML 1.1 treats no, yes, on, off, y and n as booleans, and several widely used parsers still follow it. Quote the value to keep it a string.
- Will conversion preserve comments?
- No. JSON has no comment syntax, so comments are lost as soon as YAML becomes JSON and cannot be recovered. Edit YAML as YAML when the comments matter.
- Why is yaml.load dangerous in Python?
- Without a safe loader it can construct arbitrary Python objects from YAML tags, which makes untrusted YAML a remote code execution vector. yaml.safe_load restricts it to plain data types.