About the YAML to JSON
Convert YAML to JSON and see exactly what a parser reads from your file. Anchors and merge keys are expanded, several --- documents become one JSON array, big integers keep every digit, and errors give the line and column of the problem.
You'll need this when an API, a CLI flag or a test only takes JSON, or when a config file behaves oddly. Is NO a string or false? Did the merge key copy the right settings? The JSON answers that, and it lets you run jq on a long Kubernetes file.
The converter follows YAML 1.2 with the core schema, plus the << merge key that Compose and CI files use. That means no and on stay strings and dates stay text. Your YAML is converted in the browser, so internal hostnames and other config details don't leave your machine.
- Paste YAML into YAML Input, or click Load sample for a settings file with a comment, a date, an anchor and a multi-line string.
- Read the result under JSON Output; it follows each edit you make to the YAML. If the YAML can't be parsed, an Invalid YAML box shows the reason with its line and column.
- Pick 2 spaces or 4 spaces in the Indent menu.
- Press Sort keys to order object keys from A to Z at every level. Big integers stay exact either way.
- Take the JSON with Copy, or Download gives you
converted.json. - Click Swap: JSON to YAML to go the other way.
Inputx-defaults: &defaults
image: my-app:1.4
restart: always
services:
web:
<<: *defaults
command: npm start
worker:
<<: *defaults
restart: on-failureOutput{
"x-defaults": {
"image": "my-app:1.4",
"restart": "always"
},
"services": {
"web": {
"image": "my-app:1.4",
"restart": "always",
"command": "npm start"
},
"worker": {
"image": "my-app:1.4",
"restart": "on-failure"
}
}
}<<: *defaults copies the keys of the &defaults block into each service. A key written next to it wins, so the worker keeps restart: on-failure.
Inputkind: Service
metadata:
name: web
---
kind: ConfigMap
metadata:
name: web-configOutput[
{
"kind": "Service",
"metadata": {
"name": "web"
}
},
{
"kind": "ConfigMap",
"metadata": {
"name": "web-config"
}
}
]A file with one document gives a single object. Two or more give an array in file order.
Inputcountries: [GB, NO, SE]
debug: off
mode: 0755
port: 22:22
released: 2024-01-15Output{
"countries": [
"GB",
"NO",
"SE"
],
"debug": "off",
"mode": 755,
"port": "22:22",
"released": "2024-01-15"
}PyYAML 6, a YAML 1.1 parser, reads the same file as NO = False, off = False, 0755 = 493 (octal), 22:22 = 1342 (base 60) and a date object.
What each YAML feature becomes in JSON
JSON has fewer types than YAML, so some things change on the way. Every result below comes from this converter:
- Comments are dropped. JSON has no place for them.
|keeps line breaks: ascript: |block withnpm ciandnpm testgives"npm ci\nnpm test\n".>folds the lines into one, with spaces between them. Adding-(|-or>-) removes the final line break.~,null,Null,NULLand an empty value all becomenull. Onlytrueandfalse(alsoTrue,TRUEand so on) become booleans.- Numbers:
0x1Fgives 31,0o755gives 493, and6.02e23gives6.02e+23. Trailing zeros go, so1.10becomes1.1; quote version numbers. YAML 1.2 doesn't allow_in numbers, so1_000_000stays the string"1_000_000". - Integers of any size stay exact:
user_id: 12345678901234567890comes out as12345678901234567890, not a rounded value. .infand.nanbecomenull, because JSON has no infinity or NaN.- Explicit tags work:
!!str 123gives the string"123". - Anchors (
&name) and aliases (*name) are written out as full copies, because JSON has no references. A tiny file with nested aliases can expand to gigabytes (the "billion laughs" attack), so the converter stops above 200,000 values.
Why YAML parsers disagree
YAML 1.1 (2005) reads many plain words as booleans, numbers or dates. The YAML 1.2 core schema (2009) keeps only true, false and null (plus a few capitalizations and ~) as special words. Many tools still use 1.1 rules, for example PyYAML and sigs.k8s.io/yaml, the Go library behind Kubernetes, so one file can produce different data in different tools.
In YAML 1.2, octal needs the 0o prefix: 0o755 gives 493, while 0755 is the decimal 755. If a value must stay text, such as a country code, a version like 1.10, a postal code with a leading zero or a port mapping, quote it. The JSON to YAML converter adds those quotes for you.
Common YAML errors
Each message below is what the converter shows, followed by the line and column:
- A tab used for indentation:
tab characters must not be used in indentation. YAML allows only spaces. - One space too many or too few:
bad indentation of a mapping entry. Keys at the same level need exactly the same indentation. - A value with a colon and a space, like
title: Note: read me:bad indentation of a mapping entry (line 1, column 12). Put the value in quotes. - A value that starts with
*:cron: */15 * * * *givesunidentified alias "/15" (line 1, column 11), because*starts an alias. Quote it. - An inline list that isn't closed, like
key: [1, 2followed by another key:missed comma between flow collection entries. - The same key twice in one mapping:
duplicated mapping key, pointing at the second one. - A custom tag such as CloudFormation's
!Ref:BucketName: !Ref MyBucketgivesunknown tag !<!Ref> (line 1, column 26). Write the long form,Ref: MyBucket, instead. - A missing space after the colon gives no error at all, which is worse:
name:webbecomes the single string"name:web", not a key and a value.
Convert YAML to JSON in code
Watch for dates and multiple documents. PyYAML turns 2024-01-15 into a date that json.dumps can't write without default=str, and safe_load fails on a file with more than one document, so use safe_load_all there. js-yaml's default schema turns the same date into "2024-01-15T00:00:00.000Z"; pass CORE_SCHEMA to keep it as text. Ruby's safe_load refuses dates unless you allow the Date class.
import json, yaml
with open("config.yaml") as f:
data = yaml.safe_load(f)
print(json.dumps(data, indent=2, default=str))const fs = require("fs");
const yaml = require("js-yaml");
const data = yaml.load(fs.readFileSync("config.yaml", "utf8"), {
schema: yaml.CORE_SCHEMA,
});
console.log(JSON.stringify(data, null, 2));yq -o=json '.' config.yamlimport "sigs.k8s.io/yaml"
j, err := yaml.YAMLToJSON(yamlBytes)require "date"
require "json"
require "yaml"
data = YAML.safe_load(File.read("config.yaml"), permitted_classes: [Date], aliases: true)
puts JSON.pretty_generate(data)Why is no a string in my JSON and not false?
The converter follows YAML 1.2, where only true and false are booleans. Words like no, yes, on and off stay strings. YAML 1.1 parsers such as PyYAML read them as booleans, so quote them if other tools read the same file.
What happens to YAML comments?
They're dropped, because JSON has no comment syntax. If a comment carries information you need, move it into a real key such as description before converting.
Why are my dates strings in the JSON?
JSON has no date type, and the YAML 1.2 core schema doesn't convert dates, so 2024-01-15 stays exactly as written. Other tools may turn it into a full timestamp like 2024-01-15T00:00:00.000Z.
Are big numbers like 64-bit IDs kept exactly?
Yes. Integers above 9007199254740991 (2^53 - 1) come out with every digit, with or without Sort keys, while many JavaScript-based converters round them.
How large a YAML file can I convert?
Files with up to 200,000 values convert in the browser. Every mapping, list, string, number and null counts as one value, after anchors are expanded. A typical Helm values file or Compose file is far below that.
How can I explore the JSON after converting?
Copy it into the JSON Formatter to browse it as a collapsible tree, minify it or check its size.