YAML vs JSON: Differences, Examples and When to Use Each

YAML vs JSON, in short: both are text formats for the same kinds of data (objects, lists, strings, numbers, booleans and null). JSON is strict, uses braces and quotes, and is the default for web APIs. YAML uses indentation, allows comments, anchors and several documents per file, and is popular for configuration. YAML 1.2 is almost a superset of JSON.

Try it free: YAML to JSON Converter - Convert YAML to JSON Online Free to use, no account needed.

JSON (JavaScript Object Notation, defined in RFC 8259) was designed for programs exchanging data. So what is YAML? Its name stands for "YAML Ain't Markup Language", and it was designed for people reading and editing data by hand. This guide shows the same data in both formats, compares them and covers the gotchas of each. To see how any file looks in the other format, paste it into the free YAML to JSON converter or the JSON to YAML converter.

The same data in JSON and YAML

Here is a small application config in JSON:

{
  "name": "web-app",
  "version": "2.4.1",
  "replicas": 3,
  "debug": false,
  "database": {
    "host": "db.example.com",
    "port": 5432
  },
  "features": ["login", "search"],
  "maintainer": null
}

And the same data in YAML, plus a comment, which JSON cannot hold:

# Settings for the web app
name: web-app
version: 2.4.1
replicas: 3
debug: false
database:
  host: db.example.com
  port: 5432
features:
  - login
  - search
maintainer: null

Both parse to exactly the same object. JSON marks structure with {}, [], commas and quotes; YAML marks it with indentation, key: value pairs and - for list items. Most strings in YAML need no quotes at all, which is why it reads more like a settings file than code.

YAML vs JSON: key differences

JSON YAML
Structure Braces, brackets and commas Indentation (spaces only)
Comments Not allowed # comment
Strings Always in double quotes Usually unquoted; 'single' or "double" quotes when needed
Data types Object, array, string, number, boolean, null The same, plus optional tags, timestamps in some schemas and custom types
Reuse None Anchors &, aliases * and merge keys <<
Several documents per file No (one value per file) Yes, separated by ---
Multiline text Only with \n escapes Block scalars | and >
Parsing Small, strict grammar; built into browsers and many standard libraries Larger grammar; usually a third-party library
Typical uses REST APIs, package.json, logs, data sent between programs Kubernetes manifests, GitHub Actions workflows, Docker Compose, Ansible

Some formats accept both: OpenAPI descriptions can be written in either, and kubectl apply reads JSON manifests as well as YAML ones. In general, JSON wins when programs write and read the data; YAML wins when people maintain it by hand and need comments.

Is YAML a superset of JSON?

Nearly. The YAML 1.2 specification (2009) set out to make YAML a strict superset of JSON, and in practice a YAML 1.2 parser reads almost any JSON document and returns the same data. Two caveats:

The reverse is not true: most YAML is not valid JSON.

YAML gotchas to know

The Norway problem: NO becomes false

In YAML 1.1, the unquoted words yes, no, on and off (in lower case, capitalised or upper case) are booleans, along with true and false. So this list of country codes:

countries:
  - GB
  - NO
  - SE

loads as ["GB", false, "SE"] in a YAML 1.1 parser such as PyYAML. The same rule turns the on: key of a GitHub Actions workflow into the boolean True when you load the file with PyYAML. The YAML 1.2 core schema fixed this: only true and false (also written True or TRUE) are booleans, so a 1.2 parser keeps NO as a string. Because you rarely control which parser reads your file, the safe habit is to quote such values: - "NO".

Numbers that are not meant to be numbers

Tabs and significant whitespace

The YAML specification forbids tab characters for indentation, so a tab at the start of a line is a syntax error, not a style issue. Indentation also carries meaning: moving a key two spaces to the left moves it to a different parent object, and the file can stay perfectly valid while meaning something else.

Multiline strings: | and >

A literal block (|) keeps line breaks; a folded block (>) joins lines with spaces:

literal: |
  Line one
  Line two
folded: >
  This long sentence is
  folded into one line.

literal becomes "Line one\nLine two\n" and folded becomes "This long sentence is folded into one line.\n". Both keep one final newline; write |- or >- to remove it.

Anchors, aliases and merge keys

YAML can define a block once and reuse it:

defaults: &defaults
  adapter: postgres
  port: 5432
production:
  <<: *defaults
  host: db.example.com

&defaults names the block, *defaults refers to it, and << merges its keys, so production ends up with adapter, port and host. JSON has no equivalent: converting to JSON copies the values into every place they are used. Merge keys come from YAML 1.1 and are not part of the 1.2 core schema, but most widely used parsers still support them.

JSON gotchas to know

JSON is strict, and three rules cause most errors:

This file therefore fails with JSON.parse:

{
  // port for local development
  'port': 8080,
  "tags": ["api", "v2",],
}

For hand-written files, relaxed variants exist: JSONC ("JSON with comments") is used by VS Code settings and tsconfig.json, and JSON5 also allows single quotes, unquoted keys and trailing commas. Neither is accepted by a standard JSON parser. The JSON Formatter accepts JSON5 input, marks it as "Valid JSON5 — converted to strict JSON", and gives you standard JSON back.

.yaml vs .yml

YAML vs YML is not a format question: both extensions mean the same format, and parsers don't care which one you use. RFC 9512, which registered the application/yaml media type in 2024, calls .yaml the preferred extension and notes that .yml is still used. The YAML project's FAQ also recommended .yaml, and Docker Compose looks for compose.yaml before compose.yml. GitHub Actions accepts both in .github/workflows. Pick one per project and don't keep config.yaml and config.yml side by side.

Security: load untrusted YAML safely

Full YAML loaders can build language-specific objects from tags. In Python, yaml.load(data, Loader=yaml.UnsafeLoader) can create arbitrary Python objects and, with a crafted file, run code. Always use yaml.safe_load() for files you did not write; it only builds plain dicts, lists, strings, numbers, booleans and null. Since PyYAML 6.0, yaml.load() refuses to run without an explicit Loader. Also be careful with deeply nested aliases ("billion laughs" files) that expand into huge structures. JSON has no tags or aliases, so JSON.parse and Python's json.loads only ever return plain data.

Converting between YAML and JSON

Both converters run entirely in your browser and use the open-source yaml library for JavaScript.

The YAML to JSON converter parses YAML 1.2, expands anchors and aliases, applies << merge keys, and turns a file with several --- documents into a JSON array. You can choose 2, 3 (the default) or 4 spaces, tabs or minified output, sort keys alphabetically, and download the result as converted.json. Syntax errors, such as a tab used for indentation, are shown with their line and column. Comments are lost, because JSON cannot store them.

The JSON to YAML converter reads standard JSON and JSON5, so comments and trailing commas in the input are accepted but not carried over. It writes YAML with two-space indentation and has no options. The output follows YAML 1.2: strings such as "0755" and "true" are quoted, but NO, yes or on stay unquoted because they are ordinary strings in 1.2. If a YAML 1.1 tool such as PyYAML will read the file, add quotes to those values yourself.

On the command line, Mike Farah's yq converts in both directions, and jq validates and pretty-prints JSON:

yq -o json config.yaml
yq -P -oy config.json
jq . config.json

When to use YAML and when to use JSON

The JSON vs YAML decision usually comes down to who writes the file:

If you choose YAML, keep it boring: two-space indentation, quotes around anything that could be read as a boolean or number, and a linter such as yamllint in CI.

FAQ

Is YAML better than JSON?

Neither is better in general. JSON is simpler and stricter, which makes it the safer choice for data exchanged between programs. YAML is easier for people to read and edit and supports comments, which is why so many configuration files use it.

Can I use JSON inside a YAML file?

Yes. YAML's flow style uses the same brackets as JSON, so ports: [80, 443] or db: {"host": "localhost"} works inside a YAML file, and a YAML 1.2 parser accepts almost any complete JSON document. Duplicate keys are the main exception.

Can JSON have comments?

Not in standard JSON: RFC 8259 has no comment syntax, and JSON.parse fails on // or /* */. Some tools accept JSONC or JSON5, which allow comments, but you must remove them before passing the file to a strict parser.

What is the difference between YAML and YML?

There is none in content: .yaml and .yml are two file extensions for the same format. RFC 9512 names .yaml as the preferred one, but YAML parsers don't care about the extension.

Why does YAML turn NO or on into false or true?

Because YAML 1.1 treats yes, no, on and off as booleans. YAML 1.2 only treats true and false as booleans, but many parsers, including PyYAML, still use the 1.1 rules. Put quotes around such values, for example country: "NO", and every parser will read them as strings.

Try it free: YAML to JSON Converter - Convert YAML to JSON Online Free to use, no account needed.