JSON vs YAML — When to Convert
YAML 1.2 is a strict superset of JSON, which means every valid JSON document is also valid YAML. So why convert at all? The answer is readability. JSON's braces, brackets, and quoted keys make it dense and hard to edit by hand. YAML uses indentation and newlines instead, producing files that humans can scan and modify — the reason Kubernetes manifests, GitHub Actions workflows, Docker Compose files, and Ansible playbooks all use YAML.
You'll want to convert JSON to YAML when:
- An API returns JSON but the config format for your deploy target is YAML.
- You're migrating from a JSON-based tool (npm) to a YAML-based one (Ansible, K8s).
- You want to add comments — JSON does not support them, YAML does.
- You're documenting an API response for humans who need to read it.
Basic Conversion Example
Starting JSON:
{
"name": "web-app",
"version": "1.0.0",
"dependencies": {
"react": "^18.2.0",
"next": "^14.0.0"
},
"scripts": [
"build",
"start",
"test"
]
}Equivalent YAML (block style, 2-space indent):
name: web-app
version: 1.0.0
dependencies:
react: ^18.2.0
next: ^14.0.0
scripts:
- build
- start
- testNotice how the YAML has no quotes on simple strings and no braces/brackets — the indentation defines structure. This is the idiomatic form and what tools like yq, js-yaml, and PyYAML produce by default.
Convert JSON to YAML in Python (PyYAML)
# pip install pyyaml
import json
import yaml
raw = '{"name": "web-app", "version": "1.0.0", "port": 3000}'
data = json.loads(raw)
# Basic conversion
yaml_str = yaml.safe_dump(data, default_flow_style=False)
print(yaml_str)
# Better: preserve key order and Unicode
yaml_str = yaml.safe_dump(
data,
sort_keys=False, # preserve insertion order
default_flow_style=False, # block style (readable)
indent=2, # 2-space indent (Kubernetes convention)
allow_unicode=True, # keep non-ASCII characters readable
width=999, # don't wrap long lines
)
print(yaml_str)Why safe_dump instead of dump? yaml.dumpcan emit Python-specific tags like !!python/objectfor objects it doesn't recognise. safe_dump only emits standard YAML types — the output is portable and safe to load in any language.
Convert JSON to YAML in Node.js (js-yaml)
// npm install js-yaml
const yaml = require('js-yaml');
const fs = require('fs');
// From a JSON string
const raw = '{"name": "web-app", "port": 3000, "flags": ["--verbose"]}';
const data = JSON.parse(raw);
const yamlStr = yaml.dump(data, {
indent: 2, // 2-space indent
lineWidth: -1, // don't wrap long lines
noRefs: true, // disable anchors/aliases
sortKeys: false, // preserve insertion order
});
console.log(yamlStr);
// From a JSON file
const jsonData = JSON.parse(fs.readFileSync('config.json', 'utf-8'));
fs.writeFileSync('config.yaml', yaml.dump(jsonData, {indent: 2, lineWidth: -1}));js-yaml is the library used inside Kubernetes tooling, ESLint, Prettier, and countless CI systems — battle-tested and stable. It also supports YAML 1.1 quirks (like on: true being interpreted as boolean) which can bite you on GitHub Actions files. Quote keys like "on" and "yes" defensively.
Convert JSON to YAML from the Command Line (yq)
# Install yq (Mike Farah's Go version — the most popular)
brew install yq
# or: docker run --rm -v $PWD:/workdir mikefarah/yq
# Convert JSON file to YAML
yq eval -P file.json > file.yaml
# Pipe JSON to yq
cat data.json | yq eval -P
# Fetch API JSON and convert on the fly
curl -s https://api.github.com/repos/kubernetes/kubernetes | yq eval -P
# Convert multiple files with a bash loop
for f in *.json; do
yq eval -P "$f" > "${f%.json}.yaml"
donePreserving Key Order
By default, PyYAML and some YAML libraries sort keys alphabetically. For API responses and config files where order carries meaning (Kubernetes manifests, for example, expect apiVersion and kindnear the top), you must explicitly disable sorting:
- Python:
yaml.safe_dump(data, sort_keys=False) - Node.js:
yaml.dump(data, {sortKeys: false})(default in recent versions) - yq: preserves order by default when using
eval -P
Handling Long Strings and Multi-Line Values
YAML has two block scalar styles for multi-line strings:
# Literal block (|): preserves newlines
description: |
This is a multi-line description
with two paragraphs.
Each newline is kept.
# Folded block (>): collapses newlines into spaces
summary: >
This becomes a single long string
even though it spans multiple lines
in the source file.PyYAML and js-yaml choose the style automatically based on string content, but you can force a style with custom presenters. For most JSON→YAML conversions the automatic choice works fine.
Common Gotchas When Converting JSON to YAML
- Boolean-looking strings. JSON
"yes"stays a string when converted, but YAML 1.1 parsers (like older js-yaml versions) can misread bareyesoronas boolean true. Modern libraries default to YAML 1.2 which fixes this — but downstream tools may not. Quote defensively. - Number precision. JSON allows arbitrary-precision numbers as long as they parse. YAML libraries typically coerce to double-precision float, which can lose precision on integers larger than 2^53. Consider representing large integers as strings.
- Tab vs space indent.YAML does not allow tabs for indentation. If your JSON contains tab-indented pretty-printed content, that's fine — the tabs live inside string values, not structure. The YAML output uses spaces.
- Duplicate keys. YAML allows duplicate keys (last wins). JSON technically also allows them but most parsers treat this as an error. Neither behaviour is portable — sanitise on the way in.
- Comments. One of the main reasons to convert to YAML is comment support (
# like this). Comments are not preserved on a YAML→JSON→YAML round-trip because JSON doesn't support them.
Reverse: YAML to JSON
Converting the other way is just as easy. All three tools support both directions:
- Python:
json.dumps(yaml.safe_load(open("file.yaml")), indent=2) - Node.js:
JSON.stringify(yaml.load(fs.readFileSync("file.yaml", "utf-8")), null, 2) - yq:
yq eval -o=json file.yaml
Key Facts
- Standard:
- YAML 1.2 is a strict superset of JSON
- Python library:
- PyYAML (pip install pyyaml)
- Node library:
- js-yaml (npm install js-yaml)
- CLI tool:
- yq (brew install yq)
- File extensions:
- .yaml preferred (YAML 1.2), .yml also accepted
- Round-trip safe?
- Yes for standard types; comments and formatting are not preserved
Related JSON Tools
- Format JSON Online — validate JSON before converting
- JSON Formatter Python — related Python guide
- JSON Formatter JavaScript — Node.js JSON handling
- Validate JSON Online — check syntax before conversion
- Sort JSON Keys — canonical JSON for reproducible YAML
- Minify JSON Online — compact JSON before conversion