Developer10 min readUpdated 2026-10-05

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.

  1. Open the YAML ↔ JSON Converter.
  2. Click JSON to YAML at the top. (Click YAML to JSON for the other direction.)
  3. Paste your JSON into the Input JSON box.
  4. Click Convert. The YAML appears in the output box on the right.
  5. Click Copy and paste the result into your .yaml or .yml file.

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

  1. Open the YAML ↔ JSON Converter. YAML to JSON is selected by default.
  2. Paste your YAML into the Input YAML box.
  3. 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-15

Here is what each one produced:

YAML valueFileNautyq 4.54Python (PyYAML 6)Node (js-yaml 4, defaults)
country: NO"NO""NO"false"NO"
enabled: yes"yes""yes"true"yes"
version: 1.101.11.101.11.1
zip: 0123412341234668 (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.json

JSON to YAML:

yq -p=json -o=yaml config.json > config.yaml

Two 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=yaml is explicit and works either way.
  • yq does not quote risky strings. As shown above, "yes" comes out as a bare yes. That is valid YAML 1.2, but a YAML 1.1 reader (Python's PyYAML, Ruby, many older tools) will read it as true. 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.json

Method 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 turns 2024-01-15 into a Python date, and json.dump crashes on it with TypeError: Object of type date is not JSON serializable. default=str writes the date back out as "2024-01-15".
  • sort_keys=False: without it, PyYAML sorts every key alphabetically, so name no longer comes first.
  • allow_unicode=True and ensure_ascii=False: without them, Zürich is written as "Z\xFCrich" in YAML and "Z\u00fcrich" in JSON. Both are technically correct and both are unreadable.
  • safe_load, never load: safe_load only builds plain data. Plain load with 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 unquoted 22:22 is 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, info and paths stay at the top. Quote the version: openapi: "3.0.3" is safe either way, but a bare version: 1.10 inside info would become 1.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, !Sub and !GetAtt are not standard YAML, so general converters stop with unknown tag !<!Ref>. Use AWS's own free cfn-flip instead (pip install cfn-flip, then cfn-flip template.yaml template.json). In our test it turned !Ref Bucket into {"Ref": "Bucket"} and !GetAtt Bucket.Arn into {"Fn::GetAtt": ["Bucket", "Arn"]}, and converted back again.

Troubleshooting common YAML and JSON errors

ErrorWhat it meansFix
tab characters must not be used in indentationA tab is hiding in the indentationReplace tabs with spaces on that line
bad indentation of a mapping entryA key is indented one space more or less than its neighboursLine it up with the keys at the same level
duplicated mapping keyThe same key appears twice in one objectDelete or rename one of them
unknown tag !<!Ref>CloudFormation short-form tagsUse cfn-flip
expected a single document in the streamSeveral --- documents, read by a single-document functionsafe_load_all / loadAll, or the browser converter
Expected double-quoted property name in JSONA trailing comma or a single-quoted keyRemove the comma; use double quotes
Unexpected end of JSON inputThe 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 .yaml or .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?▼
Open the FileNaut YAML ↔ JSON Converter, click JSON to YAML, paste your JSON and click Convert. It is free with no sign-up, and the conversion runs in your browser, so nothing is uploaded.
How do I convert YAML to JSON?▼
In the browser, paste the YAML into the YAML ↔ JSON Converter and click Convert. On the command line, run 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?▼
Unquoted YAML values are guessed. Depending on the tool, 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?▼
Yes. The browser converter turns a file with several --- 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?▼
No. JSON has no comment syntax, so every converter drops YAML comments. Converting back to YAML will not bring them back. Keep your original YAML file if the comments matter.
How do I convert an OpenAPI or Swagger JSON file to YAML?▼
Paste the spec into the converter with JSON to YAML selected, or run 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?▼
Use AWS's free 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?▼
Yes. Since YAML 1.2, every valid JSON document is also valid YAML, so YAML tools can read JSON directly. The reverse is not true: comments, anchors and unquoted strings have no JSON equivalent. See YAML vs JSON for the full comparison.

Ready to try it?

Use the tool right now — free, no signup, no upload.