JSON Input

YAML Output

Success
Warning

What is a JSON to YAML Converter?

You usually reach for this conversion for one of two reasons. Either a tool only accepts YAML — Kubernetes, Helm, GitHub Actions, Docker Compose, Ansible, OpenAPI — and what you have is a JSON blob from an API or an export. Or you have a config that has grown past the point where a reviewer can tell what any of it means, and you want to move it somewhere you can write comments next to the values. This page does the mechanical part: paste JSON on the left, get YAML on the right as you type.

Worth knowing up front: YAML 1.2 is a strict superset of JSON, so your JSON was already valid YAML before you converted anything. {"plan": "Unlimited 5G"} parses fine in any YAML 1.2 parser. What the conversion buys you is the readable block style — no braces, no quotes on most keys, no trailing-comma landmines — and, more importantly, somewhere to put a # comment. That is the real reason to make the trip; the YAML 1.2.2 spec says as much in its introduction.

The conversion runs on js-yaml's dump() with two-space indentation, noRefs on, and a 100-column wrap. It parses your input with JSON.parse first, so anything RFC 8259 rejects — trailing commas, single quotes, unquoted keys, comments — is reported with a line and column instead of silently mangled. Everything happens in your browser tab. API keys, connection strings, and subscriber records never leave the machine.

How to Convert JSON to YAML

  1. Paste Your JSONDrop an API response, a config file, or an export into the left panel. Use Sample if you just want to see what the output looks like, and Upload for a .json file on disk.
  2. Watch the YAML AppearThere is no Convert button. A 300 ms debounce re-runs the conversion once you stop typing, so the right panel always reflects what is currently in the editor.
  3. Fix the Line It NamesIf the JSON does not parse you get something like Invalid JSON (line 4, column 22): Expected ',' or '}' after property value. Count to that line on the left; the real mistake is on it or on the line above it.
  4. Read the QuotingThe converter quotes any string that a YAML parser might otherwise read as a number, a boolean, or null — 'NO', 'yes', '1.20', '447700900142'. Those quotes are load-bearing. Do not tidy them away.
  5. Add Your Comments, Then CopyCopy puts the YAML on your clipboard; Download saves it as converted.yaml. Once it is in your editor, annotate the values that need explaining — that is the whole point of moving to YAML.

Pro Tip: Treat the converted YAML as the new source of truth, not a cache of the JSON. The moment you add a comment, converting back to JSON destroys it — JSON has no comment syntax and no library can invent one. If you need both formats in a repo, generate the JSON from the YAML in a build step, never the other way around.

Example

A subscriber provisioning record. Notice what dump() decided to quote: 'NO', because a YAML 1.1 parser reads a bare NO as boolean false; '1.20', because bare 1.20 is the float 1.2; and '447700900142', because a bare digit string is a number. Everything unambiguous — Unlimited 5G, true, -92 — is left plain.

JSON → YAML Convert
subscriber.jsonJSON
{
  "subscriberId": "SUB-1001",
  "msisdn": "447700900142",
  "plan": "Unlimited 5G",
  "roaming": true,
  "country": "NO",
  "firmware": "1.20",
  "rsrp": -92,
  "apns": [
    { "name": "internet", "qci": 9 }
  ]
}
subscriber.yamlYAML
subscriberId: SUB-1001
msisdn: '447700900142'
plan: Unlimited 5G
roaming: true
country: 'NO'   # quoted, or YAML 1.1 reads it as false
firmware: '1.20' # quoted, or it becomes the number 1.2
rsrp: -92
apns:
  - name: internet
    qci: 9

Common Use Cases

Turning an API Payload into a Kubernetes or Helm File

Half the time you already have the shape you want — it came out of a kubectl get -o json, a Terraform state file, or a vendor's API. Converting it to YAML gets you something you can drop into a manifest, a Helm values.yaml, or a ConfigMap without hand-retyping every key. The Kubernetes object documentation covers what the fields mean once they are in front of you; note that a manifest still needs its own apiVersion, kind, and metadata, which no converter can guess.

Making a Config Reviewable

A 400-line JSON config is unreadable in a pull request: every line ends in a comma, half the diff is punctuation, and there is nowhere to explain why qci is pinned to 9. Convert it to YAML, add a comment above each value that would otherwise generate a review question, and the next person to touch the file knows what they are looking at. This is the one capability YAML has that JSON structurally cannot copy.

Writing OpenAPI, CI, and Compose Files by Hand

Tooling emits OpenAPI documents as JSON, but nobody wants to hand-edit an OpenAPI JSON file, and GitHub Actions workflows and Compose files are YAML by convention anyway. Converting once, at the start, saves you fighting quotes and braces for the rest of the file's life.

Key Features

  • Real-Time Conversion – YAML updates as you type; a short debounce keeps large payloads responsive.
  • Line and Column on Parse ErrorsJSON.parse reports a character offset; this page turns it into a line and column you can navigate to.
  • Ambiguity-Safe Quoting – Strings that would read back as booleans, numbers, or null are quoted automatically. That is what keeps "NO" from becoming false.
  • Aliases Off by DefaultnoRefs: true means repeated objects are written out in full instead of becoming &anchor / *alias pairs that confuse readers.
  • Two-Space Block Style – Standard indentation with a 100-column wrap, matching what Kubernetes and CI tooling expect.
  • Privacy First – Everything runs in your browser. No upload, no server, no logs.

Frequently Asked Questions

If YAML is a superset of JSON, why convert at all?

Because "valid" and "useful" are different things. YAML 1.2 is a strict superset of JSON, so {"plan": "Unlimited 5G", "roaming": true} is already a legal YAML document — you could rename the file to .yaml and most parsers would accept it. What you get from an actual conversion is block style: plan: Unlimited 5G on one line and roaming: true on the next, with no braces, no commas, and no quotes on the key. That is what makes a diff readable and a comment possible. The superset rule is still handy to remember, though — it is why you can paste raw JSON into a Helm values file or a CI config and it just works.

What do I actually gain by moving to YAML?

Comments, mostly. JSON has no comment syntax at all — not //, not #, not /* */ — so the only way to annotate a JSON config is to invent a fake key like "_comment": "..." and hope nothing validates against it. In YAML you write:
# qci 9 until the core upgrade in Q3 — do not raise
qci: 9
That comment lives next to the value, survives code review, and is invisible to the parser. Secondary gains: multi-line strings via | and > block scalars, and no trailing-comma errors.

Why is "NO" quoted in the output? (The Norway problem)

Because an unquoted NO is a booby trap. YAML 1.1 treats yes, no, on, off, y, and n as booleans, so a country list written as - NO parses to false and Norway silently disappears. This is the famous "Norway problem" and it still bites, because PyYAML, Ruby's Psych, and older Go YAML libraries all implement 1.1 semantics. YAML 1.2 narrowed booleans to true/false, but you rarely control which parser reads your file downstream. So the converter emits country: 'NO' with the quotes — and if you strip them to make the file look tidier, you have reintroduced the bug. The same applies to 'yes', 'off', and 'null'.

Why is my version number quoted?

Same defensive reason. Unquoted 1.20 is a float, and the float 1.20 is the number 1.2 — the trailing zero has no arithmetic meaning, so version: 1.20 becomes 1.2 and your v1.20 release now reads as v1.2. The converter writes version: '1.20' to prevent that. Long digit strings get the same treatment: iccid: '8944500102030405060' stays a string, because unquoted it would be a number past JavaScript's safe integer range and would come back as 8944500102030405000. Rule of thumb: if it is an identifier rather than a quantity, it belongs in quotes.

Can I indent the output with tabs?

No, and neither can any conformant YAML file — the spec forbids tab characters in indentation outright. This is the single most common YAML error, because a tab-indented file looks perfectly aligned in an editor and then fails to parse with a message about indentation that points at the wrong line. The output here is always spaces, two per level. If you paste it into an editor that auto-converts leading spaces to tabs, the file will break; set expandtab (or the equivalent) for .yaml and .yml.

Why does my repeated block appear twice instead of using an anchor?

Because noRefs: true is set. YAML can define a block once with an anchor and reuse it with an alias — defaults: &defaults then prod: *defaults — which is genuinely useful for hand-written configs. But when a converter generates them automatically, you get anchors in surprising places purely because two objects happened to be the same reference in memory, and readers find that confusing. So repeated content is written out in full. If you want the sharing, add the anchors yourself afterwards, where you know which duplication is deliberate. Note that anchors are a YAML-only feature: convert such a file back to JSON and every alias expands into a full copy.

What happens to null, empty objects, and empty arrays?

null becomes null, an empty object becomes {}, and an empty array becomes [] — YAML's flow style is used for empties because there is no block form for "nothing". Note that YAML also accepts a bare ~ or an empty value as null, so tac: with nothing after it means tac: null. That trips people up when they delete a value and leave the key behind.

Does the conversion lose anything?

Structurally, no — every JSON value has a YAML equivalent, which is what being a superset means. The things to watch are cosmetic or downstream: key order is preserved as-is (YAML mappings are ordered on paper but some parsers do not guarantee it), very long strings wrap at 100 columns, and non-ASCII characters are written literally rather than escaped. Nothing is dropped.

Is my data safe?

Yes. Parsing and dumping both run in your browser with JSON.parse and js-yaml. Nothing is uploaded, cached, or logged — which matters here, because the configs people convert are exactly the files that hold API keys and database passwords.

Related Tools

  • YAML to JSON – The reverse trip — turn a manifest or pipeline back into JSON for jq and schema validators.
  • JSON Formatter – Tidy and re-indent the JSON before you convert it.
  • JSON Validator – Find out exactly why a payload will not parse, with the error spelled out.
  • JSON to XML – Same idea for the systems that still want an XML document.
  • JSON to Table – Preview the JSON as a table to sanity-check the shape before converting.

Useful Resources

  • YAML 1.2.2 Specification – The official spec, including the section that declares YAML a superset of JSON.
  • js-yaml – The library behind this page — its dump() options are the ones used here.
  • RFC 8259 – The IETF JSON specification — what the input has to satisfy.
  • YAML Multiline Strings – A visual cheatsheet for the pipe and folded block styles once you start editing by hand.
  • Kubernetes Objects – Field reference for the manifests this conversion usually feeds.
  • MDN JSON.parse – What counts as valid JSON input, and the errors it throws when it is not.