JSON ↔ YAML Converter
Convert JSON to YAML or YAML to JSON, and see what changed on the way: comments that JSON can't
hold, anchors that were expanded, and values like NO or
3.10 that YAML tools disagree about. Config files often hold hostnames and
secrets, so everything happens in your browser and nothing is uploaded.
JSON and YAML
JSON and YAML describe the same kinds of data: mappings of keys to values, lists, strings, numbers, booleans and null. YAML 1.2 was designed so that every JSON document is also valid YAML, which is why JSON converts to YAML without losing anything, and why this converter reads JSON pasted into the YAML side without complaint.
The other way round, YAML has features JSON lacks, so some things change. The converter lists each one it finds under the input, with line numbers:
| In YAML | In JSON |
|---|---|
| Comments (# ...) | Dropped: JSON has no comments |
| Anchors and aliases (&name, *name) | Expanded: each alias becomes a full copy |
| Merge keys (<<: *name) | Applied: the merged keys are copied in |
| Several documents separated by --- | One JSON array, one item per document |
| Keys that are numbers, booleans or lists | Turned into strings: "1", "true" |
| Custom tags (!Ref, !Sub) | Dropped, the value kept as written |
| .inf and .nan | null: JSON has no infinity or NaN |
| !!binary | A Base64 string |
The Norway problem: YAML 1.1 and 1.2
In YAML 1.1, an unquoted NO is the boolean false, so a list of country
codes loses Norway. YAML 1.2, from 2009, fixed this, and this converter reads YAML by its rules.
But many widely used libraries still follow 1.1, including PyYAML, SnakeYAML (and so Spring Boot)
and Ruby's Psych, so the same file can mean different things to different tools:
| Unquoted | YAML 1.2 | YAML 1.1 |
|---|---|---|
| NO | "NO" (a string) | false |
| yes | "yes" (a string) | true |
| on | "on" (a string) | true |
| off | "off" (a string) | false |
| y | "y" (a string) | true |
| 0755 | 755 (a number) | 493 (a number) |
| 0o755 | 493 (a number) | "0o755" (a string) |
| 1:20 | "1:20" (a string) | 80 (a number) |
| 2026-10-05 | "2026-10-05" (a string) | 2026-10-05 (a date) |
| 1_000 | "1_000" (a string) | 1000 (a number) |
The 1.1 spec makes y and n booleans too, but
PyYAML, for one, reads them as strings. When converting JSON to YAML, this tool quotes every string
that either version could misread, so the output means the same to both. When converting YAML to
JSON, it points out each value a 1.1 tool would read differently. A common case is the
on: key of a GitHub Actions workflow, which PyYAML loads as
True.
Multi-line strings: | and >
A block scalar starts with | (literal: keep the line breaks) or
> (folded: join lines with spaces), and the text goes on the indented
lines below. A - or + after it decides what
happens to the line breaks at the end. Here is what each makes of the lines
one and two followed by a blank line:
| Marker | Meaning | As a JSON string |
|---|---|---|
| | | Keep line breaks, one newline at the end | "one\ntwo\n" |
| |- | Keep line breaks, no newline at the end | "one\ntwo" |
| |+ | Keep line breaks and every trailing blank line | "one\ntwo\n\n" |
| > | Fold lines into spaces, one newline at the end | "one two\n" |
| >- | Fold lines into spaces, no newline at the end | "one two" |
When a YAML string needs quotes
Most strings can be written bare, but some need quotes to stay strings or to parse at all:
| Quote it when | Examples |
|---|---|
| It would read as a boolean, null or number | "NO", "on", "null", "3.10", "0755" |
| It starts with a YAML indicator | "- item", "#tag", "*star", "&", "!bang", "@at", "`tick" |
| It contains ": " or " #" | "key: value", "a #b" |
| It starts or ends with a space, or is empty | " padded ", "" |
| It contains a tab or other control character | "a\tb" (double quotes for escapes) |
Single quotes take everything literally (write '' for a single quote inside).
Double quotes understand escapes such as \n and
\t, like JSON strings.
FAQ
Is JSON valid YAML?
Yes, for practical purposes: YAML 1.2 is a superset of JSON, so a YAML 1.2 parser reads any JSON document. Older YAML 1.1 parsers almost always do too. So you can often paste JSON straight into a YAML config file.
Why did 3.10 become 3.1?
Unquoted, 3.10 is a number, and the number 3.10 is 3.1. It's a common
bug with Python versions in CI files: python-version: 3.10 asks for Python
3.1. Write "3.10". The converter warns about every number that loses
a trailing zero.
Does the converter keep key order?
Yes, in both directions. That's worth checking in other tools: JavaScript's
JSON.parse moves keys that look like whole numbers to the front of each
object, and rounds integers larger than 253. This converter reads JSON with a YAML
parser instead, so {"b": 1, "2": 2} stays in that order and
12345678901234567890 keeps every digit.
Can I convert a CloudFormation template?
JSON to YAML, yes. YAML to JSON works too, except for the short-form tags like
!Ref and !Sub: JSON has no tags, so the
converter keeps the value, drops the tag and tells you the long form to use instead, such as
{"Ref": "MyBucket"} or {"Fn::Sub": "..."}.
Does YAML allow tabs?
Not for indentation: YAML indents with spaces only, and a tab there is an error. Tabs are fine inside strings and between a value and a comment.
How do I convert on the command line?
With yq, yq -o=json file.yaml and yq -p json -o yaml file.json. With Python and PyYAML installed, python3 -c 'import sys, json, yaml; print(json.dumps(yaml.safe_load(sys.stdin), indent=2))'
< file.yaml, which reads YAML 1.1, with the differences above.
Related tools
- JSON Formatter & Validator — Format, validate and minify JSON; points to the exact error line.
- Cron Expression Explainer — A cron schedule in plain English, with its next 10 run times.
- Format Identifier — Paste anything to find out what it is (a JWT, JSON, a certificate, Base64, a cron schedule and more), then open it in the right tool.