YAML ↔ JSON Converter

Convert YAML configuration files to JSON and vice versa.

About the YAML to JSON converter

YAML and JSON describe the same data model: mappings, sequences, strings, numbers, booleans and null. The difference is the surface syntax. JSON is strict, quotes everything and has no comments; YAML uses indentation, allows comments, anchors and multi-line text, and since the 1.2 specification (2009) every valid JSON document is also valid YAML. Infrastructure tooling (Kubernetes, GitHub Actions, Docker Compose, Ansible, OpenAPI) is written in YAML, while APIs, JSON Schema validators and jq want JSON, so the conversion comes up daily.

This page converts in both directions as you type, using the js-yaml 4 parser, which follows the YAML 1.2 core schema. It handles one document at a time. Errors replace the output with the parser message, including the line and column and a caret under the offending token. Swap pushes the output back into the input and converts the other way, which is a quick way to normalise a file: YAML in, JSON out, YAML back.

How YAML becomes JSON on this page

  • Booleans. Only true and false (in any letter case) become booleans. yes, no, on and off stay strings, so the on: key of a GitHub Actions workflow comes out as the string "on", not true.
  • Numbers. 0755 is decimal 755; octal needs the 0o prefix (0o755 is 493). 0x1F is 31, 1e3 is 1000, 1_000 is 1000 and 1.10 prints as 1.1. Integers above 253 (about 9 quadrillion) are rounded because JavaScript stores them as floating point, so quote long IDs.
  • Dates. An unquoted 2024-01-01 is parsed as a timestamp and printed as "2024-01-01T00:00:00.000Z". A time with an offset such as 10:00:00+05:30 is rewritten in UTC. Quote dates that must stay text.
  • Null. ~, null and an empty value after a colon all become null. .inf and .nan also become null, because JSON cannot represent them.
  • Keys. JSON object keys are always strings, so a numeric or boolean key (1:, true:) is quoted as "1" or "true". Duplicate keys are rejected with "duplicated mapping key"; PyYAML would silently keep the last one.
  • Anchors, aliases and merge keys. &base, *base and <<: *base are expanded, so the JSON contains copies. An alias that refers to its own parent cannot be serialised and produces a "circular structure" error.
  • Text. A plain scalar continued on the next line folds into one line with a space. | keeps line breaks, > folds them. Tabs in indentation are an error. Base-60 values such as 1:30 stay strings here; YAML 1.1 parsers read them as the number 90.
  • Custom tags. Anything the core schema does not know, including CloudFormation short forms such as !Ref and !Sub, stops the parse with "unknown tag". Convert those templates with the AWS cfn-flip tool instead.

How JSON becomes YAML

The dump uses two-space indentation, puts list items under their key, keeps the key order of the JSON and never invents anchors. Strings that a YAML reader might mistake for something else are single-quoted: 'yes', '123', 'true', '2024-01-01', a value containing : , a value starting with # or a space, and the empty string. Keys get the same treatment. This quoting is deliberately conservative so the output is also safe for YAML 1.1 readers. Strings longer than 80 characters are folded into a >- block and strings with line breaks become a | literal block; both are exactly equivalent to the original text. Empty objects and arrays print as {} and [].

The YAML 1.1 versus 1.2 trap

YAML 1.1 (2005) treated yes, no, on and off as booleans, 0755 as octal and 1:30 as base 60. The 1.2 revision removed all of that, but PyYAML and a number of other widely used libraries still implement the 1.1 rules. The classic casualty is a country code: country: NO becomes false in a 1.1 parser, which is why the problem is nicknamed after Norway. Docker Compose documents a related one: a port mapping such as 22:22 written without quotes can be read as a base-60 number.

Quote anything that only looks like text to you

Version numbers ("1.10"), postal codes with leading zeros, phone numbers, git hashes that happen to be all digits and an e, country codes, and any value that could be a date or a boolean should be quoted in YAML. The converter shows you how a 1.2 parser reads them; your production tool may not agree.

Working with real configuration files

  • Kubernetes. Manifest files often hold several documents separated by ---. Convert them one at a time, or let the cluster do it: kubectl get deploy web -o json and kubectl apply -f file.json both work, because kubectl accepts either format.
  • Helm. Chart templates contain {{ .Values.name }} placeholders and are not valid YAML until rendered. Run helm template first and convert the output.
  • OpenAPI and JSON Schema. OpenAPI documents may be written in either format, and the conversion is lossless apart from comments, so authoring in YAML and publishing JSON is a common workflow.
  • Comments. JSON has none, so every comment is dropped on the way to JSON. To reformat YAML while keeping comments, use the File Formatter, which prints the file without reinterpreting it.

Command-line equivalents

# PyYAML (pip install pyyaml). Note: YAML 1.1 rules, so "no" becomes false
python3 -c 'import sys, json, yaml; print(json.dumps(yaml.safe_load(sys.stdin), indent=2))' < config.yaml

# yq v4 (the Go version by mikefarah)
yq -o=json '.' config.yaml        # YAML to JSON
yq -P '.' config.json             # JSON to YAML

# Node with js-yaml, the same parser as this page
node -e "const y=require('js-yaml');const fs=require('fs');console.log(JSON.stringify(y.load(fs.readFileSync(0,'utf8')),null,2))" < config.yaml

Always use safe_load with PyYAML; the plain load can construct arbitrary Python objects from a crafted file. js-yaml 4 is safe by default and this page never evaluates anything.

Privacy

Parsing and serialising happen in your browser. Kubernetes secrets, CI configuration with tokens and internal API payloads are never sent anywhere; even so, prefer converting a redacted copy when a file contains live credentials.

How to use

  1. Choose the direction with the YAML to JSON or JSON to YAML toggle.
  2. Paste into the input. The output updates as you type; a parse error replaces it with the message, line and column.
  3. Press Swap to push the output back into the input and convert the other way, which normalises a file in one round trip.
  4. Copy the output with the Copy button; Clear resets both panes.

Common use cases

  • Turning a Kubernetes manifest into JSON to query it with jq or apply a JSON patch.
  • Converting a GitHub Actions workflow or Docker Compose file to JSON so a JSON Schema validator can check it.
  • Switching an OpenAPI specification between YAML for editing and JSON for publishing.
  • Reading a dense JSON API response as YAML, where nesting is easier to follow by eye.
  • Checking how a YAML 1.2 parser interprets ambiguous values such as 0755, 1e3, NO or 2024-01-01 before they reach production.

Frequently asked questions

Does it support multi-document YAML files?

No. A file with more than one document separated by --- produces the error "expected a single document in the stream, but found more". Split the file at the separators and convert each part, or use yq or kubectl, which handle streams.

Are comments preserved?

No. JSON has no comment syntax, so comments are dropped when converting to JSON, and they cannot come back when you convert to YAML again. Use the File Formatter to tidy YAML while keeping its comments.

Why did my date turn into a timestamp string?

Unquoted values that look like dates are parsed as timestamps under the YAML core schema and JSON has no date type, so they are printed as ISO 8601 strings in UTC. A value with a +05:30 offset is therefore rewritten as a UTC time. Quote the value in YAML to keep it as text.

Why is "no" a string here but false in my Python script?

This page follows YAML 1.2, where only true and false are booleans. PyYAML implements YAML 1.1, where yes, no, on and off are also booleans. The safe fix in either world is to quote the value.

Why does 0755 become 755?

YAML 1.2 reads a leading zero as part of a decimal number, so 0755 is seven hundred and fifty-five. Octal requires the 0o prefix, and 0o755 converts to 493. Tools built on YAML 1.1 read 0755 as octal, which is why file modes in Ansible playbooks (parsed by PyYAML) are written with the leading zero.

What happens to anchors, aliases and merge keys?

They are resolved during parsing, so the JSON output contains full copies of the shared data and the merged mapping. Converting back to YAML does not recreate the anchors. An alias that points at its own ancestor cannot be represented in JSON and produces an error.

Why are some strings quoted in the YAML output?

Strings that a YAML parser could mistake for a boolean, number, date, null, comment or nested mapping are wrapped in single quotes so they survive a round trip through any parser, including YAML 1.1 ones. Everything else is written plain.

Why does my CloudFormation template fail with an unknown tag?

Short-form intrinsic functions such as !Ref, !Sub and !GetAtt are custom YAML tags that the core schema does not define, so the parser stops. Use the long form (Ref: name) or convert the template with the AWS cfn-flip tool, which understands those tags.

Is my configuration uploaded?

No. Both directions run in the browser and nothing is transmitted. Redact live secrets anyway before pasting anything into any tool.

Advertisement