YAML is a superset of JSON, which is exactly the trap
Every valid JSON document is also valid YAML — the YAML 1.2 spec was deliberately designed that way. This makes people assume conversion is trivial, little more than reformatting braces into indentation. It mostly is, right up until a document uses something JSON has no equivalent for: anchors and aliases (&ref / *ref) for reusing a block, multiline block scalars (| and >, each with different whitespace rules), or YAML's notoriously permissive implicit typing, where an unquoted no, yes, on, off or a bare version-looking string can silently become a boolean or a number instead of the string it looked like.
That gap is why this tool uses a real YAML parser under the hood instead of pattern-matching indentation with regular expressions. A hand-rolled converter tends to work perfectly on every example in its own test suite and then mishandle the first real-world file a visitor pastes in.
Why duplicate keys are treated as an error, not a preference
YAML mappings, like JSON objects, are not supposed to repeat a key. When they do, most lenient parsers quietly keep the last value and discard the earlier one — which means a config file with a typo'd duplicate key silently loses half of what someone intended to configure, with no warning at any point.
This tool rejects duplicate keys outright rather than picking a winner for you. If your input has one, that is very likely a real mistake worth fixing before it reaches whatever reads this file in production — a CI pipeline, a Kubernetes manifest, a docker-compose file.
What gets lost going from YAML to JSON
Comments do not survive. JSON has no comment syntax, so anything after a # in your YAML is gone in the output — there is no format it could go to. If the comments matter, keep the original YAML file as the source of truth and treat the JSON as a generated artifact, not something to hand-edit and convert back.
Anchors and aliases also disappear as a *mechanism* — the tool resolves them and writes out the repeated content in full, because JSON has no way to express "this value equals that other value by reference." The resulting data is identical; only the DRYness of the source YAML is lost in translation.
Why the type coercion story matters when going JSON to YAML
The direction that surprises people least is JSON to YAML: since JSON is a YAML subset, this conversion is close to lossless, and the only real judgment calls are cosmetic — block sequences (- item) versus flow sequences ([item]), and how wide a line can get before it wraps. This tool prefers block style and a 100-character line width, which reads more naturally for a human than the more compact flow style.
A boolean stored as JSON true comes back out as unquoted YAML true — which is exactly the kind of bare word that, if you ever hand-edit that YAML file later and add a new key with an unquoted yes or no, gets reinterpreted as a boolean rather than the string you meant. Quoting string values that could be mistaken for booleans, numbers or null is a defensive habit worth keeping when editing YAML by hand.