Skip to content

YAML ⇔ JSON Converter

Convert between YAML and JSON. Ideal for converting configuration file formats and editing Kubernetes manifests, Docker Compose, GitHub Actions, and OpenAPI specs.

100% Free No signup Browser-only 5 languages Dark mode

Supported Formats

If something is broken or not displaying correctly, let us know via the contact form.

📖 Where people get stuck

Converts between YAML and JSON using js-yaml, which follows YAML 1.2, with anchors and aliases, multiple documents and line numbers on syntax errors. Everything runs in the browser. The difficulty with YAML is not its syntax but the type coercion that happens silently and that you never asked fora value you meant as a string becomes a number or a boolean, and no error is raised, so you go looking for the cause only after something stops working.

Case What happens What to do
A value you meant as a string becomes a number or a boolean YAML guesses the type of an unquoted value from how it looks. The usual breakages: version: 1.10 becomes a number and equals 1.1; zip: 0070 can be read as octal; country: NO, meaning Norway, is false under YAML 1.1; and the on: key of a GitHub Actions workflow becomes the key true under 1.1. This tool follows YAML 1.2, so NO and on stay strings — but PyYAML by default and Ruby Psych still behave like 1.1, so the same file means different things in different implementations. When in doubt, quote it. Always quote version numbers, country codes, postcodes, numbers with a leading zero, yes, no, on, off, true, false, null, ~, and any value containing : or #. Quoting is not verbosity; it is a statement of intent. If a reviewer asks why only this value is quoted, that is a good question, and the answer is that you have decided this value is a string. Before a config file goes into the repository, convert it to JSON once and read the types with your own eyes — seeing 1.1 rather than "1.1" in the output on this page is the warning sign.
Anchors and aliases are expanded and the references vanish Defining &defaults and pulling it in with <<: *defaults is a powerful way to remove duplication from YAML, but JSON has no such concept. Converting therefore expands every merge for real and produces JSON with the same content repeated over and over. That much is expected; the problem is what happens when you convert backthe anchors are not reconstructed, and a config file that was written DRY turns into a long, fully spelled-out one. In files that lean on shared definitions, such as docker-compose.yml or .gitlab-ci.yml, the line count multiplies. Do not round-trip configuration files. Edit the YAML as the source of truth and generate JSON only as the final output for a machine — CI posting JSON to an API is exactly that case. If you are handed a YAML file whose anchors are already gone, there is no mechanical way to restore them: you find the duplication by eye and factor it back out by hand. Which is why the repository should make it obvious which file is authoritative — if you commit generated JSON, put it under something like generated/ or head it with a do-not-edit, auto-generated comment, and the accidents drop away.
You cannot find the indentation error YAML does not accept tab characters as indentation — a single stray tab from an editor setting makes it fail every time, and on screen it is indistinguishable from spaces. Worse is the line the error points at: a YAML parser reports the line where it noticed the structural contradiction, so the actual mistake is routinely several, or several dozen, lines above. In a deeply nested Kubernetes manifest, that is why being told the error is at line 120 and searching from line 118 finds nothing. Start by enabling convert tabs to spaces in your editor; putting [*.yml] indent_style = space in .editorconfig protects the whole team. When chasing an error, read upward from the reported line, looking for the place where the indentation is one level off. Also, list indentation has two permitted styles — the - either in the same column as its parent or two spaces in — and both are correct, but mixing them in one file is how humans misread it. Putting yamllint in CI catches this class of problem the moment it is written, which is enormously cheaper than finding it at runtime.

When parsing YAML from an external source on a server, always use the safe loader. Python yaml.load() can construct arbitrary Python objects, so feeding it a crafted document leads to code execution — use yaml.safe_load(). js-yaml made safe behaviour the default in v4, but projects on older versions must say safeLoad explicitly. This page runs in the browser and is equivalent to safe, so it is not a concern here. Second, mind how multiple documents are handled: Kubernetes puts several resources in one file separated by ---, and JSON has no notion of multiple documents, so they become an array. Forget to restore the --- separators on the way back and kubectl apply refuses it, complaining that an array is not a valid Kind — if your pipeline passes through a conversion, make sure this case is tested.

📖 How to Use

  1. 1
    Paste input
    Paste YAML or JSON on the left; the right side updates automatically.
  2. 2
    Toggle direction
    Switch YAML → JSON or JSON → YAML. Tab/space and indent width configurable.
  3. 3
    Check validation errors
    Syntax errors show line and reason — great for K8s manifests and GitHub Actions.

❓ Frequently Asked Questions

Are YAML anchors (&) and aliases (*) supported?
Yes, via js-yaml. Anchors, aliases, and tags are parsed. They get expanded when converted to JSON.
Are multi-document YAML (---) files handled?
Multi-doc YAML becomes a JSON array — works with multi-resource Kubernetes manifests.
Works with Docker Compose / K8s manifests?
Yes. Converts losslessly for CI pipelines that post to APIs as JSON.
Is the YAML Norway bug handled?
We use YAML 1.2, so NO/Yes stay strings — no Norway bug.
🐛 Found a bug or issue with this tool?

Free to use, no signup. Even just the steps to reproduce are helpful. Reports go directly to the operator and help us fix issues.

* Browser info (UA / screen / language / URL) is sent automatically to help reproduce the issue