DevKitHub

JSON & Data

JSON to YAML Converter (and YAML to JSON)

Paste JSON to get YAML, or switch direction to turn YAML into JSON. Values another YAML parser would read differently are quoted or flagged, and errors name the exact line.

11 lines
15 lines

YAML is read by the 1.2 rules, where yes, no, on and off are strings. Where a YAML 1.1 parser such as PyYAML would read a value differently, a warning names the line.

This tool runs entirely in your browser. Your input is never uploaded, stored or logged.

How it works

YAML is read by the YAML 1.2 core schema, and that is where most YAML-to-JSON surprises come from. In 1.2 only true and false are booleans; YAML 1.1, which PyYAML and Go’s yaml.v2 still implement, also reads yes, no, on and off as booleans, a leading-zero number such as 0755 as octal, and 22:22 as a base-60 number. So the country code NO becomes false, a GitHub Actions workflow’s on: key becomes true, and a docker-compose port mapping becomes 1342. This converter follows 1.2 and gives you the strings, and it warns, with the line, wherever a 1.1 parser would disagree, so you know which files are fragile.

Going the other way, a string is quoted only where leaving it bare would change it: an empty string, leading or trailing spaces, anything a 1.2 or 1.1 parser would read as a number, boolean, null or date (1.10, yes, NO, 0x1F, 2026-09-28), anything starting with a YAML indicator such as &, *, !, |, %, @ or a backtick, and anything containing ": " or " #". Multi-line strings become literal blocks, with |- when there is no final line break and |+ when there are extra ones, so the text comes back exactly. Key order is kept, including keys such as "200" that a JavaScript object would move to the front, and integers beyond 2^53 are copied digit for digit instead of being rounded.

The parser is written for this page rather than taken from a library, and it rejects what lenient parsers get wrong quietly: a tab used for indentation, a line whose indentation matches no enclosing block, a key repeated in one mapping (the spec requires unique keys; many parsers keep the last), and an alias whose anchor does not exist. Anchors, aliases and << merge keys are expanded, because JSON has no references, and expansion is capped so a "billion laughs" file stops with an error. It is tested against the YAML test suite. Not supported: custom tags such as CloudFormation’s !Ref and !GetAtt, %TAG directives, and keys that are lists or mappings — JSON can represent none of them. .inf and .nan become null with a warning, and several documents separated by --- become a JSON array.

Common problems

Every example below is run against this tool in our test suite, so what it says here is what the tool actually does.

A tab is used for indentation here.

services:
	web:
		image: nginx
Why:
The line is indented with a tab. YAML allows only spaces for indentation, and an editor that inserts tabs produces a file that looks aligned but does not parse.
Fix:
Replace the tabs with spaces, and set your editor to indent .yml and .yaml files with spaces.

Found ": " inside an unquoted value, where a new key cannot start.

title: Note: read this first
Why:
A colon followed by a space inside an unquoted value. YAML reads ": " as the separator between a key and its value, so a second one on the same line is a syntax error.
Fix:
Quote the whole value: title: "Note: read this first".

Duplicate key "image": it already appears on line 1 of this mapping.

image: nginx
ports: []
image: redis
Why:
The same key twice in one mapping, usually from a merge conflict or a paste. The spec requires unique keys, but many parsers keep the last value without a word, so the first silently disappears.
Fix:
Delete or rename one of them. To override shared settings on purpose, use an anchor and a << merge key instead.

!Ref is a custom tag: CloudFormation's short form of Ref.

BucketName: !Ref MyBucket
Why:
CloudFormation templates use short-form tags such as !Ref, !GetAtt and !Sub. They are custom YAML tags that only CloudFormation understands, and JSON has no way to carry a tag.
Fix:
Rewrite them in the long form first, Ref: MyBucket or Fn::GetAtt: [MyBucket, Arn], which is exactly what CloudFormation’s JSON templates use.

The country code NO, or the on: key of a workflow, came out as a boolean in another tool.

Why:
That tool follows YAML 1.1, where yes, no, on and off are booleans. YAML 1.2 made them strings, so the same file loads differently depending on the parser.
Fix:
Nothing to do here, since this converter reads them as strings and warns. Quote such values ("NO") so every parser agrees; JSON to YAML adds those quotes itself.

Frequently asked questions

Why does on: in my GitHub Actions workflow turn into true?
Because the tool reading it follows YAML 1.1, where on, off, yes and no are booleans; a Python script using PyYAML gets True as the key. YAML 1.2 reads it as the string "on", which is what GitHub Actions relies on and what this converter produces, with a warning. Quote it as "on": if other tools read the file.
Why did my version number 1.10 become 1.1?
Unquoted, 1.10 is a number in YAML, and a trailing zero is not part of a number. Quote it as "1.10". Converting JSON to YAML, this tool adds the quotes itself, because the JSON said it was a string.
Does it support anchors, aliases and merge keys?
Yes. JSON has no references, so each alias becomes a copy of the value its anchor marks, and << merges one or more mappings, with keys written in the mapping itself winning. Expansion is capped at a million nodes, so a "billion laughs" file fails quickly instead of freezing the page.
What happens to several documents separated by ---?
They become a JSON array with one element per document, and a warning says so. A Kubernetes file holding a Deployment and a Service comes out as a two-element array.
Why is a CloudFormation template rejected?
Because it uses short-form tags such as !Ref and !GetAtt, and JSON cannot carry a tag. Rewrite them in the long form (Ref: MyBucket, Fn::GetAtt: [MyBucket, Arn]), which is what CloudFormation’s JSON format uses anyway, and the template converts.

Last updated