Convert YAML to JSON: Command Line, Python, and JavaScript
YAML and JSON represent the same data structures — objects, arrays, strings, numbers, booleans, null — just with different syntax. YAML is meant for humans to write; JSON is meant for machines to parse. Converting between them is straightforward once you understand the mapping.
YAML vs JSON: same structure, different syntax
# YAML
name: John Doe
age: 30
active: true
tags:
- developer
- writer
address:
city: New York
zip: "10001"
{
"name": "John Doe",
"age": 30,
"active": true,
"tags": ["developer", "writer"],
"address": {
"city": "New York",
"zip": "10001"
}
}
Same data. YAML uses indentation and colons; JSON uses braces, brackets, and commas.
Python: PyYAML + json
pip install pyyaml
import yaml
import json
# YAML string → JSON string
yaml_text = """
name: John Doe
age: 30
active: true
tags:
- developer
- writer
"""
data = yaml.safe_load(yaml_text)
json_text = json.dumps(data, indent=2)
print(json_text)
From a file:
import yaml, json
with open("config.yaml", "r") as f:
data = yaml.safe_load(f)
with open("config.json", "w") as f:
json.dump(data, f, indent=2)
Always use yaml.safe_load() instead of yaml.load(). The load() function can execute arbitrary Python code embedded in YAML — a serious security risk if the YAML comes from an untrusted source.
Python: JSON to YAML
import yaml, json
with open("config.json", "r") as f:
data = json.load(f)
with open("config.yaml", "w") as f:
yaml.dump(data, f, default_flow_style=False, allow_unicode=True)
default_flow_style=False forces block style (indented) rather than inline {key: value} style.
JavaScript / Node.js: js-yaml
npm install js-yaml
const yaml = require('js-yaml');
const fs = require('fs');
// YAML file → JSON string
const yamlText = fs.readFileSync('config.yaml', 'utf8');
const data = yaml.load(yamlText);
const jsonText = JSON.stringify(data, null, 2);
fs.writeFileSync('config.json', jsonText);
JSON to YAML:
const yaml = require('js-yaml');
const fs = require('fs');
const data = JSON.parse(fs.readFileSync('config.json', 'utf8'));
const yamlText = yaml.dump(data);
fs.writeFileSync('config.yaml', yamlText);
Command line (no code)
yq is a YAML/JSON command-line processor (like jq but for YAML):
# Install
brew install yq # macOS
snap install yq # Linux
# YAML → JSON
yq -o=json config.yaml
# JSON → YAML
yq -o=yaml config.json
# Write to file
yq -o=json config.yaml > config.json
Python one-liner (no install needed beyond Python itself):
python3 -c "import sys, yaml, json; print(json.dumps(yaml.safe_load(sys.stdin), indent=2))" < config.yaml
Things that don't convert cleanly
A few YAML features have no direct JSON equivalent:
- Comments —
# this is a comment— dropped entirely in the conversion. - Multi-document YAML — a file with multiple
---separators — you'd need to handle each document separately. - Custom types (
!!python/object) — safe_load rejects these; they have no JSON mapping. - Anchors and aliases (
&anchor/*alias) — these are expanded by the YAML parser before JSON serialization, so you lose the deduplication but the data is preserved. - Non-string keys — YAML allows keys like
123ortrue; JSON requires string keys. Most parsers stringify them, but it's worth knowing.
Key takeaways
- Python:
yaml.safe_load()→json.dumps()— one round-trip, two lines. - JavaScript:
js-yamlprovidesyaml.load()andyaml.dump(). - Command line:
yq -o=jsonconverts in one shot. - Use
safe_loadin Python — neveryaml.load()with untrusted input. - YAML comments, anchors, and multi-document files don't survive the round-trip to JSON.