About the JSON to YAML
Convert JSON to YAML for Kubernetes manifests, Docker Compose files, GitHub Actions workflows and other config. Strings that a YAML parser could misread, such as NO, 01234, yes or on, are put in quotes, so the YAML means exactly what your JSON meant.
YAML holds the same data as JSON, but it uses indentation instead of braces, drops most quotes and lets you add # comments. That's why tools you edit by hand, like Kubernetes, Ansible and most CI systems, prefer it. You'll usually reach for this converter when you have JSON from an API, from kubectl get -o json or from a script, and you need it in a file that people will review.
The output is block-style YAML from the js-yaml library, with line wrapping turned off so long strings stay on one line. No server is involved: the conversion happens in the page itself.
- Paste JSON into JSON Input, or click Load sample for a small user profile with a nested address, a list and a
null. - Read the result under YAML Output, which refreshes after a short pause in your typing. If the JSON has a syntax error, an Invalid JSON box shows the message with its line and column; the JSON Formatter also prints the broken line with a
^under the problem. - Set Indent to 2 spaces or 4 spaces. There's no tab choice, because the YAML spec forbids tabs for indentation.
- Press Sort keys to put object keys in A to Z order at every level. Press it again to go back to the order of your JSON.
- Copy the YAML, or download it as
converted.yaml. If a note above the YAML says an integer is larger than JavaScript can store exactly, quote that number in your JSON and convert again. - Need the other direction? Swap: YAML to JSON opens the reverse converter.
Input{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"app-config","namespace":"shop"},"data":{"LOG_LEVEL":"info","ENABLE_CACHE":"yes","MAX_CONNECTIONS":"100","TZ":"Africa/Nairobi"}}OutputapiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: shop
data:
LOG_LEVEL: info
ENABLE_CACHE: 'yes'
MAX_CONNECTIONS: '100'
TZ: Africa/NairobiConfigMap values must be strings. Without the quotes, Kubernetes would read yes as a boolean and 100 as a number, and kubectl would reject the manifest.
Input{"name":"CI","on":{"push":{"branches":["main"]}},"jobs":{"test":{"runs-on":"ubuntu-latest","steps":[{"uses":"actions/checkout@v4"},{"run":"npm ci && npm test"}]}}}Outputname: CI
'on':
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm testThe key on gets quotes because YAML 1.1 reads a bare on as true. GitHub reads 'on': and on: the same way, so the workflow runs either way.
Input{"countries":["GB","NO","SE"],"zip":"01234","version":"1.10","port":"22:22","released":"2024-01-15","cron":"*/15 * * * *","note":"line 1\nline 2"}Outputcountries:
- GB
- 'NO'
- SE
zip: '01234'
version: '1.10'
port: '22:22'
released: '2024-01-15'
cron: '*/15 * * * *'
note: |-
line 1
line 2Every quoted value would turn into a boolean, a number, a date or an alias without its quotes (see below). The string with a line break becomes a |- block.
How JSON maps to YAML
Every JSON type has a direct YAML form:
- An object becomes a mapping: one
key: valueper line, with nested objects indented under their key. - An array becomes a list with one
-item per line. An array of objects puts the first key on the dash line, like- name: web. - Strings lose their quotes unless YAML would read them as something else. Values that start with a character YAML treats specially (
#,&,*,!,@,?or-), contain:, end in:, or are empty get single quotes. - Numbers,
true,falseandnullkeep their type. Numbers are printed the way JavaScript prints them, so59.90becomes59.9and1e3becomes1000. Empty arrays and objects stay inline as[]and{}. - A string with line breaks becomes a literal block (
|or|-), which keeps every line break. A string with a tab or a carriage return gets double quotes with\tor\rescapes instead.
Why some values get quotes
Many YAML parsers still follow YAML 1.1, which turns more plain words into booleans, numbers and dates than YAML 1.2 does. PyYAML and the Go library behind kubectl are two of them. Here's what PyYAML 6 reads when these values aren't quoted:
yes,no,onandoff, in their usual capitalizations, become booleans. This is the "Norway problem": the list[GB, NO, SE]loads as['GB', False, 'SE']. The YAML 1.1 spec also listsyandn, so the converter quotes those as well.01234becomes 668, because YAML 1.1 reads a leading zero as octal. A YAML 1.2 parser reads 1234. Either way, a postal code loses its zero.1.10becomes the float 1.1, which breaks version numbers.22:22becomes 1342, because YAML 1.1 reads base-60 numbers. That's why Docker's Compose docs ask for port mappings as quoted strings.2024-01-15becomes a date object, not a string.- A value that starts with
*is read as an alias, so an unquoted cron schedule like*/15 * * * *is a parse error. The Cron Expression Generator explains what such a schedule means.
When to keep JSON and when to switch
Keep JSON for data that programs send to each other. It's strict, every language reads it the same way, and there's no indentation to get wrong. Switch to YAML for files that people write and review, where comments and fewer quotes matter more than strictness.
You don't always have to convert. YAML 1.2 treats JSON as valid YAML, and kubectl apply -f accepts a .json manifest directly. Convert when a team will edit the file, when you want to add comments, or when a tool only documents YAML examples.
Convert JSON to YAML in code
PyYAML sorts keys unless you pass sort_keys=False, and it doesn't indent list items under their key. Both styles are valid YAML.
import json, yaml
with open("config.json") as f:
print(yaml.safe_dump(json.load(f), sort_keys=False))const fs = require("fs");
const yaml = require("js-yaml");
const data = JSON.parse(fs.readFileSync("config.json", "utf8"));
console.log(yaml.dump(data, { lineWidth: -1 }));yq -p json -o yaml config.json > config.yamlimport "sigs.k8s.io/yaml"
y, err := yaml.JSONToYAML(jsonBytes)require "json"
require "yaml"
puts JSON.parse(File.read("config.json")).to_yamlIs JSON valid YAML?
Almost always. YAML 1.2 was designed as a superset of JSON, so most YAML parsers load a JSON file without changes. Converting still makes the file easier to read, review and comment.
Why is the key on in quotes in my GitHub Actions workflow?
A bare on means true in YAML 1.1, so the converter quotes it to be safe. GitHub's own parser treats on: as the trigger key either way, so you can remove the quotes if you prefer the style of GitHub's docs.
Does the converter keep the order of keys?
Yes, keys stay in the order of your JSON, with one exception: keys that are whole numbers, like "2" or "10", move to the front in numeric order, because JavaScript objects always put them first. Press Sort keys for A to Z order instead.
Why did a large number change?
Integers above 9007199254740991 (2^53 - 1) can't be stored exactly in JavaScript, so they're rounded and a warning appears above the YAML. Put such IDs in quotes in the JSON to keep every digit.
Can I add comments to the YAML?
Yes. After converting, add a comment on its own line, or after a value with a space before the #. JSON has no comments, so there are none to carry over.
How do I convert YAML back to JSON?
Click Swap: YAML to JSON, or open the YAML to JSON converter. It expands anchors and merge keys, and turns a file with several --- documents into a JSON array.