How to Convert JSON to YAML (and Back)
A practical guide to converting between JSON and YAML — format differences, conversion rules, gotchas with types, and code examples.
JSON vs YAML — key differences
YAML is a superset of JSON — every valid JSON document is valid YAML. YAML is designed for human readability: it uses indentation instead of braces and brackets, and quotes are usually optional. JSON is strict and unambiguous; YAML has many implicit type conversions that can surprise you.
// JSON
{
"name": "Alice",
"age": 30,
"active": true,
"tags": ["admin", "user"]
}
# Equivalent YAML
name: Alice
age: 30
active: true
tags:
- admin
- userConverting JSON to YAML in JavaScript
import yaml from 'js-yaml';
const obj = JSON.parse(jsonString);
const yamlString = yaml.dump(obj, {
indent: 2,
lineWidth: 120,
noRefs: true,
});
console.log(yamlString);Converting YAML to JSON in JavaScript
import yaml from 'js-yaml';
const obj = yaml.load(yamlString);
const jsonString = JSON.stringify(obj, null, 2);
console.log(jsonString);Converting in Python
import json, yaml
# JSON → YAML
obj = json.loads(json_string)
yaml_string = yaml.dump(obj, default_flow_style=False, allow_unicode=True)
# YAML → JSON
obj = yaml.safe_load(yaml_string) # always use safe_load
json_string = json.dumps(obj, indent=2)Type gotchas to watch for
YAML's implicit typing causes silent data changes when converting. The most common problems: bare 'yes', 'no', 'on', 'off', 'true', 'false' (case-insensitive) are parsed as booleans. Bare numbers that look like octals (e.g. 0777) are parsed as integers in YAML 1.1. Timestamps like 2024-01-15 are parsed as date objects, not strings. Quote these values in YAML if they should be strings.
# YAML 1.1 surprises
active: yes # → boolean true (not string 'yes')
mode: 0755 # → integer 493 in YAML 1.1 (octal)
date: 2024-01-15 # → Date object, not string
port: 8080 # → integer 8080 (fine)
# Fix: quote the values that should be strings
active: 'yes'
mode: '0755'
date: '2024-01-15'Multiline strings in YAML
YAML has two multiline string styles. The literal block scalar (|) preserves newlines. The folded block scalar (>) folds newlines into spaces, useful for long prose.
# Literal block — newlines preserved
description: |
Line one.
Line two.
Line three.
# Folded block — newlines become spaces
message: >
This is a long sentence that will be
folded into a single line with spaces.Is YAML always better than JSON for config files?
YAML is more readable for humans writing config by hand. JSON is safer for machine-generated config — there are no implicit type conversions and any JSON parser is unambiguous. For APIs and data interchange, prefer JSON. For config files edited by humans (CI pipelines, Docker Compose, Kubernetes), YAML is conventional.
Why should I use yaml.safe_load instead of yaml.load in Python?
yaml.load can deserialise arbitrary Python objects from YAML input, which is a remote code execution vulnerability if the YAML comes from an untrusted source. yaml.safe_load only parses standard YAML types (strings, numbers, lists, dicts) and is safe to use on untrusted input.
How to Validate JSON
A practical guide to checking JSON for syntax errors, understanding common mistakes, and formatting it for readability.
Read guide →How to Read and Write CSV
A practical guide to the CSV format — structure rules, edge cases with quotes and commas, parsing in JavaScript and Python, and common pitfalls.
Read guide →