JSON to YAML: A Practical Guide for Kubernetes, CI, and Configs
Why Convert JSON to YAML
JSON dominates APIs and data interchange. YAML dominates configuration: Kubernetes manifests, Docker Compose, GitHub Actions, GitLab CI, Ansible playbooks, Helm charts, OpenAPI specs, and Rails-era `*.yml` files. You inevitably need a bridge — a script returns JSON and you want to commit it as a config, or a colleague hands you an API payload and you need to fold it into a values file.
A naive converter (a one-line `yaml.dump(json.load(...))`) gets most of the easy cases right and silently breaks on the hard ones. Here's what a good JSON-to-YAML conversion actually has to handle.
The Type Preservation Problem
YAML 1.1 famously parses `yes`, `no`, `on`, `off`, `y`, `n` as booleans. This is the **Norway problem**: the country code `NO` becomes `false`. YAML 1.2 dropped this, but plenty of parsers (especially older PyYAML configurations) still default to 1.1 semantics. A safe converter quotes any string that could be misread as a boolean:
```json
{"country": "NO", "active": "yes", "id": "123"}
```
must become:
```yaml
country: "NO"
active: "yes"
id: "123"
```
Without the quotes, `country` becomes `false`, `active` becomes `true`, and `id` becomes the integer `123` — three silent type changes that will break the next system to read this file.
Special Characters in Strings
YAML reserves a long list of characters that start or appear inside scalars: `:`, `#`, `-`, `?`, `@`, ````, `|`, `>`, `!`, `%`, `&`, `*`, `,`, `[`, `]`, `{`, `}`, plus leading or trailing whitespace. A string like `"http://example.com"` is fine unquoted, but `": no"` (used as a key like `":"`) needs quoting. Our converter detects these and emits double-quoted YAML with proper escaping.
Indentation Matters (a Lot)
YAML is whitespace-sensitive. The community standard for Kubernetes, Docker Compose, and most cloud-native tools is **2 spaces**. Ansible playbooks often use 4 spaces, and tabs are forbidden everywhere. Our converter emits consistent block-style indentation with the indent you pick:
```yaml
server:
host: api.example.com
port: 8443
tags:
- prod
- us-east
```
Notice the array items use `- ` at the parent's indent level — that's the block sequence form, more readable than the flow-style `[prod, us-east]` for anything non-trivial.
Arrays of Objects: The Tricky Bit
The most common shape in config files is an array of objects (containers in a pod, jobs in a workflow, hosts in an inventory):
```json
{"users": [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]}
```
The idiomatic YAML form puts the first key on the same line as the dash and aligns subsequent keys underneath:
```yaml
users:
- id: 1
name: Alice
- id: 2
name: Bob
```
This is the form Kubernetes, Compose, and Helm all expect. Our converter emits this shape automatically.
The Document Start Marker
YAML 1.2 allows multiple documents in one stream, separated by `---`. A standalone document doesn't strictly need a leading `---`, but it's idiomatic for Kubernetes manifests (especially when you concatenate several into a single file with `kubectl apply -f`). Toggle it on for multi-doc files; leave it off for single-resource configs.
When YAML Is the Better Choice
Pick YAML when humans edit the file: configs, pipelines, manifests, infrastructure-as-code. The anchor/alias syntax (`&base`, `*base`) lets you DRY up repeated blocks, and comments are first-class. Pick JSON when machines exchange it: APIs, structured logs, data pipelines, anywhere you want a minimal parser surface.
Round-Tripping
YAML is a strict superset of JSON, so every JSON file is valid YAML. The reverse isn't true — YAML features like anchors, tagged scalars, and multi-document streams have no JSON equivalent. Convert JSON → YAML freely; convert YAML → JSON only when you're sure the YAML doesn't use YAML-only features.
Conclusion
JSON to YAML is one of those conversions that looks trivial and is actually full of footguns: the Norway problem, ambiguous-looking strings, special characters, indentation conventions, array-of-object formatting. A good converter handles all of these silently so the YAML you get works the first time, in production, with the tool you're targeting. Our [JSON to YAML converter](/json-to-yaml) does exactly that — paste, click, ship the config.