How to Convert JSON to YAML (and YAML to JSON)
The fastest free way to convert JSON to YAML, or YAML to JSON, is the FileNaut YAML ↔ JSON Converter. Pick a direction, paste your data, and click Convert. The conversion runs in your browser tab, so a config file full of hostnames, API keys or passwords is never uploaded anywhere.
The two formats describe the same things: objects, lists, strings, numbers, true/false and null. That is why the conversion is usually one click. It is also why the problems are easy to miss. A converter never complains when it turns your country code NO into false, your ZIP code 01234 into 668, or your version 1.10 into 1.1. It just does it.
Below are four free methods: the browser, the yq command-line tool, Python and Node.js. Each one was run on the same test file, and the table further down shows exactly which values each one changed. There are also fixes for the files people convert most: Kubernetes manifests, Docker Compose, OpenAPI specs, GitHub Actions workflows and CloudFormation templates.
Method 1: Convert JSON to YAML in your browser (free, no upload)
Best for: one-off conversions, API responses you want to read as config, and files you would rather not upload to a random website.
- Open the YAML ↔ JSON Converter.
- Click JSON to YAML at the top. (Click YAML to JSON for the other direction.)
- Paste your JSON into the Input JSON box.
- Click Convert. The YAML appears in the output box on the right.
- Click Copy and paste the result into your
.yamlor.ymlfile.
A few things the converter does on purpose:
- Key order is kept. Keys come out in the order they appear in your JSON. Some tools sort them alphabetically (more on that below).
- Risky strings are quoted. A JSON string such as
"yes","on","1.10"or"2024-01-15"is written as'yes','on','1.10','2024-01-15'in the YAML, so no YAML reader can mistake it for a boolean, a number or a date. - Long strings stay on one line. They are not folded into multi-line blocks.
- Lists are indented under their key with two spaces, the style most YAML files use.
If your JSON has a mistake, the converter says what and where. A trailing comma, for example, reports Invalid JSON: Expected double-quoted property name in JSON at position 7 (line 1 column 8). JSON is strict about this: no trailing commas, no single quotes, no comments. To find and fix the problem in a larger file, paste it into the JSON Formatter first.
How to convert YAML to JSON in your browser
- Open the YAML ↔ JSON Converter. YAML to JSON is selected by default.
- Paste your YAML into the Input YAML box.
- Click Convert, then Copy.
The JSON comes out indented with two spaces. Comments are dropped, because JSON has no comment syntax. Anchors and aliases (&base and *base) are expanded into full copies, and merge keys (<<: *base) are merged in, because JSON has no way to point at another part of the file.
Multi-document YAML works. A file with several documents separated by ---, like most Kubernetes manifests, converts to a JSON array with one item per document, and the converter tells you how many it found. Empty documents left by a trailing --- are ignored.
Errors point to the line. YAML errors show the line and column, for example Invalid YAML on line 3, column 2: bad indentation of a mapping entry or Invalid YAML on line 2, column 1: tab characters must not be used in indentation. The table in the troubleshooting section below explains the common ones.
What changes when you convert (tested)
YAML lets you leave strings unquoted, so a YAML reader has to guess what each bare value is. Different tools guess differently. Older readers follow the YAML 1.1 rules, where yes, no, on and off are booleans and a leading zero means an octal number. Newer ones follow YAML 1.2, which dropped most of that.
We converted this file to JSON with four tools:
name: web
country: NO
enabled: yes
version: 1.10
zip: 01234
released: 2024-01-15Here is what each one produced:
| YAML value | FileNaut | yq 4.54 | Python (PyYAML 6) | Node (js-yaml 4, defaults) |
|---|---|---|---|---|
country: NO | "NO" | "NO" | false | "NO" |
enabled: yes | "yes" | "yes" | true | "yes" |
version: 1.10 | 1.1 | 1.10 | 1.1 | 1.1 |
zip: 01234 | 1234 | 1234 | 668 (read as octal) | 1234 |
released: 2024-01-15 | "2024-01-15" | "2024-01-15" | Crashes: Object of type date is not JSON serializable | "2024-01-15T00:00:00.000Z" |
The fix is the same everywhere: quote it. Write country: "NO", version: "1.10", zip: "01234" and every tool above keeps the value exactly as written. If a value must stay text, quote it in the YAML. No converter can tell that 01234 was meant to be a ZIP code.
The same problem runs the other way. When you convert JSON to YAML, a string like "yes" has to be quoted in the output, or a YAML 1.1 reader will turn it back into true. We fed the YAML that yq wrote for {"on": "yes"} into Python, and it came back as {True: True}: the key and the value had both become booleans. FileNaut writes 'on': 'yes', which Python reads back correctly. This matters for GitHub Actions, whose workflows start with an on: key.
For more on why YAML behaves like this, see YAML vs JSON: differences and gotchas.
Method 2: Convert on the command line with yq
Best for: scripts, CI pipelines and big files. yq is a free, single-file program by Mike Farah that reads and writes YAML, JSON, XML and more. (There is an unrelated Python tool also called yq; these commands are for Mike Farah's version 4.) In our tests it was the most faithful of the command-line options: it kept NO, yes and 1.10 exactly as written.
YAML to JSON:
yq -o=json config.yaml > config.jsonJSON to YAML:
yq -p=json -o=yaml config.json > config.yamlTwo things to know:
- Always say the output format. Older tutorials use
yq -P config.json. In yq 4.54 that printed JSON again, not YAML, because yq now picks its output format from the input file's extension.-o=yamlis explicit and works either way. - yq does not quote risky strings. As shown above,
"yes"comes out as a bareyes. That is valid YAML 1.2, but a YAML 1.1 reader (Python's PyYAML, Ruby, many older tools) will read it astrue. Quote those values by hand, or use the FileNaut converter, if the YAML will be read by one of them.
A multi-document YAML file comes out of yq as several separate JSON objects, one after another, which is not one valid JSON file. To get a single JSON array instead:
yq ea -o=json '[.]' manifests.yaml > manifests.jsonMethod 3: Convert with Python
Best for: when you are already writing Python, or need to change the data on the way through. Install the YAML library once with pip install pyyaml.
YAML to JSON:
import json
import yaml
with open("config.yaml") as f:
data = yaml.safe_load(f)
with open("config.json", "w") as f:
json.dump(data, f, indent=2, default=str, ensure_ascii=False)JSON to YAML:
import json
import yaml
with open("config.json") as f:
data = json.load(f)
with open("config.yaml", "w") as f:
yaml.safe_dump(data, f, sort_keys=False, allow_unicode=True)Every option in those snippets is there because leaving it out caused a problem in our tests:
default=str: PyYAML turns2024-01-15into a Python date, andjson.dumpcrashes on it with TypeError: Object of type date is not JSON serializable.default=strwrites the date back out as"2024-01-15".sort_keys=False: without it, PyYAML sorts every key alphabetically, sonameno longer comes first.allow_unicode=Trueandensure_ascii=False: without them,Zürichis written as"Z\xFCrich"in YAML and"Z\u00fcrich"in JSON. Both are technically correct and both are unreadable.safe_load, neverload:safe_loadonly builds plain data. Plainloadwith an unsafe loader can run code hidden in a YAML file.
PyYAML follows YAML 1.1, so NO still becomes false and 01234 still becomes 668. Quote those values in the YAML. For a file with several --- documents, safe_load stops with expected a single document in the stream; use list(yaml.safe_load_all(f)) instead.
Method 4: Convert with Node.js
Best for: JavaScript projects. Install js-yaml with npm install js-yaml.
const fs = require("fs");
const yaml = require("js-yaml");
// YAML to JSON (CORE_SCHEMA keeps dates as written)
const data = yaml.load(fs.readFileSync("config.yaml", "utf8"), { schema: yaml.CORE_SCHEMA });
fs.writeFileSync("config.json", JSON.stringify(data, null, 2));
// JSON to YAML (lineWidth -1 stops long strings being folded)
const json = JSON.parse(fs.readFileSync("config.json", "utf8"));
fs.writeFileSync("config.yaml", yaml.dump(json, { lineWidth: -1 }));With the default schema, js-yaml turns 2024-01-15 into a JavaScript Date, which JSON.stringify writes as "2024-01-15T00:00:00.000Z". Passing CORE_SCHEMA keeps it as the plain string. The trade-off is that CORE_SCHEMA does not understand << merge keys; if your YAML uses them, keep the default schema. For multi-document files, use yaml.loadAll(), which returns an array.
Also from JavaScript: JSON.parse cannot hold whole numbers above 9,007,199,254,740,991. A JSON ID such as 12345678901234567890 becomes 12345678901234567000 in the YAML. That is true of the browser converter as well. Store big IDs as strings.
Kubernetes, Docker Compose, OpenAPI and CloudFormation
- Kubernetes manifests. Usually several documents in one file. The browser converter and
yq ea -o=json '[.]'both give you a single JSON array. Going back to YAML from that array gives you a YAML list, not separate---documents; convert each item on its own if you need them separate. - Docker Compose. Converts cleanly in our test, including quoted port strings such as
"80:80". Keep ports quoted: an unquoted22:22is read as a base-60 number (1342) by YAML 1.1 tools. - OpenAPI and Swagger. A spec converts like any other file, and key order is kept, so
openapi,infoandpathsstay at the top. Quote the version:openapi: "3.0.3"is safe either way, but a bareversion: 1.10insideinfowould become1.1. - GitHub Actions. Workflows are YAML only, and GitHub reads the
on:key correctly. Just be aware of it when a YAML 1.1 tool reads the same file (see the table above). - AWS CloudFormation. Short-form tags such as
!Ref,!Suband!GetAttare not standard YAML, so general converters stop with unknown tag !<!Ref>. Use AWS's own freecfn-flipinstead (pip install cfn-flip, thencfn-flip template.yaml template.json). In our test it turned!Ref Bucketinto{"Ref": "Bucket"}and!GetAtt Bucket.Arninto{"Fn::GetAtt": ["Bucket", "Arn"]}, and converted back again.
Troubleshooting common YAML and JSON errors
| Error | What it means | Fix |
|---|---|---|
| tab characters must not be used in indentation | A tab is hiding in the indentation | Replace tabs with spaces on that line |
| bad indentation of a mapping entry | A key is indented one space more or less than its neighbours | Line it up with the keys at the same level |
| duplicated mapping key | The same key appears twice in one object | Delete or rename one of them |
| unknown tag !<!Ref> | CloudFormation short-form tags | Use cfn-flip |
| expected a single document in the stream | Several --- documents, read by a single-document function | safe_load_all / loadAll, or the browser converter |
| Expected double-quoted property name in JSON | A trailing comma or a single-quoted key | Remove the comma; use double quotes |
| Unexpected end of JSON input | The JSON is cut off: a missing } or ] | Check the end of the file in the JSON Formatter |
One more that has no error message: a value that converts to the wrong type. If a string comes out as true, false or a number, go back to the YAML and put quotes around it.
Tips for clean conversions
- Any JSON file is already valid YAML. YAML 1.2 is a superset of JSON, so a YAML tool will read your JSON as it is. You only need to convert if you want the cleaner YAML style.
- Comments do not survive a round trip. JSON has nowhere to put them. Converting a commented YAML file to JSON and back loses every comment, so keep the original.
- Round-trip test anything important. Convert to JSON and back, then compare with the original. Changed values show up immediately.
- Quote anything that only looks like a number or boolean: ZIP and postal codes, phone numbers, version numbers, country codes, and the words yes, no, on and off.
- Use
.yamlor.yml. Both extensions mean the same thing. Pick the one your tool's documentation uses. - Converting other formats? The XML ↔ JSON Converter and our XML to JSON guide cover XML, and how to open a JSON file covers viewing JSON on any device.
Frequently asked questions
How do I convert JSON to YAML online for free?▼
How do I convert YAML to JSON?▼
yq -o=json config.yaml > config.json. In Python, load it with yaml.safe_load and write it with json.dump(data, f, indent=2, default=str).Why did my YAML value change when I converted it to JSON?▼
NO can become false, 1.10 can become 1.1, and 01234 can become 1234 or even 668. Put quotes around any value that must stay text.Can I convert a Kubernetes YAML file with multiple documents to JSON?▼
--- documents into a JSON array, one item per document. With yq, use yq ea -o=json '[.]' manifests.yaml. In Python, use list(yaml.safe_load_all(f)).Do comments survive converting YAML to JSON?▼
How do I convert an OpenAPI or Swagger JSON file to YAML?▼
yq -p=json -o=yaml openapi.json > openapi.yaml. Key order is kept, so the spec reads in the same order. Check that version strings stayed quoted.How do I convert a CloudFormation template between JSON and YAML?▼
cfn-flip tool: pip install cfn-flip, then cfn-flip template.yaml template.json. It understands the !Ref, !Sub and !GetAtt short forms that general YAML converters reject.Is JSON valid YAML?▼
Ready to try it?
Use the tool right now — free, no signup, no upload.