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.