JSON ⇄ YAML

Convert JSON to YAML and YAML to JSON; a hand-written parser covers common structures

JSON and YAML conversion: type traps, lost comments, and a security caveat

The two formats are not symmetric

YAML 1.2 is a superset of JSON: any valid JSON document is also valid YAML, with one minor edge case — tab characters are not allowed inside indentation. The reverse is not true. The extra power YAML carries is exactly why it is so widely used for configuration files:

CapabilityJSONYAML
CommentsNot supported# comments
Multi-line textMust be written as \n escapes| and > block scalars
Anchors and aliasesNot supported, must be repeated&anchor / *anchor
Punctuation noiseQuotes, commas, braces requiredIndentation expresses structure
ReadabilityLong documents are hard to readHierarchy is immediate

Because of this asymmetry the two conversion directions are not equal in nature: JSON to YAML is essentially lossless (it only changes the notation); YAML to JSON always loses information — comments and anchor structure cannot survive the trip.

What YAML to JSON drops

  • All comments disappear. JSON has no comment syntax; this is a hard limitation. So do not treat YAML as the only source of truth. If your workflow is "edit YAML, convert to JSON, deploy", the generated JSON can never be the input for the next edit, or your comments get wiped on every round. Keep YAML as the source and treat JSON as a generated artifact.
  • Anchors get expanded. A fragment defined by &base is copied to every reference site; the structural information is lost and the document can bloat. Reconstructing anchors in reverse is heuristic (it guesses which identical blocks to deduplicate) and you cannot rely on a tool to decide your reuse policy for you.
  • Non-string keys are forced to strings. JSON requires object keys to be strings, while YAML permits numbers, booleans, or even complex structures as keys. On conversion those keys must be stringified, so 123: value becomes "123": value — the original type information is gone and converting back will not restore it.
  • Multi-document files (--- separators) cannot be expressed by a single JSON document. You can only take one document, or wrap everything in an array.

YAML type inference is the biggest trap

JSON types are explicit: they come from quotes and literal forms, so there is no ambiguity. YAML lets you omit quotes, and the price is that the parser must guess the type, which produces a famous family of pitfalls:

Value you wroteParsed resultProblem
NO / no / offfalseThe "Norwegian problem": country code NO becomes boolean false
1.101.1Version number read as a float, trailing zero lost
01234Different per parserSome read octal, some decimal — a zip-code disaster
12:30:0045000YAML 1.1 allows sexagesimal; the time is computed as seconds
2026-01-15A date objectSerialized to an ISO time string on conversion, possibly with a timezone offset
yes / ontrue in YAML 1.1, string in 1.2The same document yields different results across versions

The conclusion is simple: any value that looks like a number, boolean, or date should always be quoted. Write the version as "1.10", the country code as "NO", and the zero-padded identifier as "01234". This is the only reliable defense; memorizing per-version differences does not work.

YAML security concerns

  • Deserialization can execute code. Some YAML libraries support custom tags that instantiate arbitrary objects when loaded (Ruby's Psych.load, old Python yaml.load behavior). Never load untrusted YAML with a loader that permits arbitrary tags; use a safe mode such as Python's safe_load or a loader bound to an explicit schema.
  • The billion-laughs anchor bomb. Nested anchor references can be crafted so the document expands exponentially. A few kilobytes of input can consume gigabytes of memory. This is also why anchor expansion must be bounded.
  • Parser implementation differences. The YAML spec is large and detailed, and implementations (PyYAML, libyaml, go-yaml, ruamel) disagree at the edges. For data exchanged across languages, use JSON; reserve YAML for config that a human writes and a single language reads.

Limits of this tool

The YAML parser in this tool is hand-written for common structures: indented maps, sequences, scalars, quoted strings, and comments. It does not implement anchors and aliases, custom tags, multi-document separators, or the fully nested flow style using {} and [].

So it is good enough for everyday editing of Kubernetes manifests, CI configuration, and docker-compose files — converting them and viewing the result quickly. For YAML generated by programs in production (which may contain anchors or complex scalars), use the official parser for that language, or a command-line tool for an authoritative conversion, then bring the result back to verify. When this tool hits a structure it cannot parse, it reports an error with the line number rather than emitting a silently wrong output.

All parsing runs locally in your browser; the configuration content is never uploaded. That matters because config files often contain internal hostnames, secret names, and account information.

FAQ

Why does the string "100" get quotes after converting to YAML?

To avoid it becoming a number when converted back to JSON. YAML identifies a plain number as an integer by default, and quotes preserve the exact original type.

Are the supported YAML features limited?

It covers the most common daily subset: maps, sequences, nesting, scalars and comments. Anchors, multi-document and complex flow styles are not supported yet.