Skip to content
FormatKit

Free online YAML to JSON converter

YAML to JSON with a receipt for what is lost

This YAML to JSON converter is free, requires no signup and handles files up to 5 MB in the browser: anchors and aliases are expanded into real copies, merge keys are written out in full, and literal and folded block scalars arrive as ordinary JSON strings. Because YAML carries several things JSON simply does not have, the panel underneath lists each one with the line it came from — comments removed, dates turned into strings, .inf turned into null, tags dropped. A selector switches between YAML 1.2 and the 1.1 rules that PyYAML and SnakeYAML still apply, so you can see both readings of the same file.

  • 100% free
  • No signup
  • Up to 5 MB
  • Anchors expanded
  • 1.1 and 1.2 schemas
JSON

The JSON appears here as you type.

Paste YAML, open a file, or press Ctrl+V anywhere on this page.

Fourteen lines in, eighteen out

This fragment uses four YAML features that JSON has no syntax for. Nothing here is exotic; it is the shape of an ordinary CI config.

YAML

# shared by both jobs
base: &base
  image: node:22
  timeout: 30

test:
  <<: *base
  run: pnpm test

build:
  <<: *base
  run: pnpm build
  cache: yes
  since: 2026-08-09

JSON, YAML 1.2 core

{
  "base": {
    "image": "node:22",
    "timeout": 30
  },
  "test": {
    "run": "pnpm test",
    "image": "node:22",
    "timeout": 30
  },
  "build": {
    "run": "pnpm build",
    "cache": "yes",
    "since": "2026-08-09",
    "image": "node:22",
    "timeout": 30
  }
}
  • The comment is gone — there is nowhere in JSON to put it.
  • &base is written out three times instead of once, because JSON cannot name a node and refer to it.
  • cache: yes is the string "yes" under YAML 1.2 and the boolean true under YAML 1.1 — the same input, two different documents, depending on which library reads it.
  • since was a date to YAML and is a string to JSON; no amount of care recovers the type.

How to convert YAML to JSON

Three steps: paste the config, match the schema to your tooling, read what the conversion dropped.

  1. Paste the config

    Kubernetes manifests, docker-compose files, GitHub Actions workflows and OpenAPI documents all parse here, %YAML directives and --- separators included. Bring one in through the editor, a .yaml or .yml file of up to 5 MB, or Ctrl+V, ⌘V on a Mac, with the editor unfocused.

  2. Pick the schema your other tools use

    YAML 1.2 core reads only true and false as booleans; YAML 1.1 — what PyYAML, SnakeYAML and Ruby's Psych still do by default — also reads yes, no, on and off, treats a leading zero as octal and turns 12:30:00 into 45000. Choose the one that matches the program on the other end, and decide whether a stream of --- documents becomes a JSON array or just its first document.

  3. Read the loss report, then copy

    Under the panels, every step the conversion could not make cleanly is listed with the line it happened on: comments removed, anchors expanded into copies, a merge key written out, a date turned into a string, .inf turned into null. Use Copy for the clipboard or Download for a .json file keeping the name of the manifest you started with.

Technical specifications

Structures readBlock mappings and sequences, flow [a, b] and {k: v} collections, plain, single- and double-quoted scalars, and compact nesting like a sequence item that starts a mapping
Block scalarsLiteral | and folded >, with strip -, clip and keep + chomping and an explicit indentation indicator such as |2
Anchors, aliases, merges&anchor recorded, *alias expanded to a full copy, << merged with explicit keys taking precedence; an undefined alias is an error naming the line
Scalar resolutionYAML 1.2 core, or YAML 1.1 with yes/no/on/off, 0755 read as octal 493, 1_000 as 1000 and 12:30:00 as 45000 — the two schemas are one selector apart
Documents and directivesA --- stream becomes a JSON array or only its first document; %YAML and %TAG directives are read, reported and dropped
Reported as lostComments, anchor names, custom tags, timestamps that become strings, .inf and .nan that become null, and non-string keys that become quoted — each with a line number
Duplicate keysLast value wins with a warning, matching PyYAML and js-yaml, or treated as the error YAML 1.2 says it is
Speed, limits and costA 64,000-line manifest of 0.96 MB carrying 8,000 aliases and 8,000 comments converts in 0.06 seconds, the alias expansion adding 24,000 nodes. 5 MB per file; free, no signup, and the whole parse runs in this browser tab

Frequently asked questions

Is JSON already valid YAML?

Yes since YAML 1.2, which was rewritten in 2009 specifically to make JSON a strict subset — so any JSON document can be handed to a YAML 1.2 parser unchanged. The reverse is not true and never was: YAML adds anchors, comments, tags, multiple documents, non-string keys and several scalar types that JSON has no syntax for. That asymmetry is the whole content of this page — converting down loses things, and the useful question is which ones.

What happens to anchors and aliases?

Each alias is replaced by a full copy of the value its anchor named, because JSON has no way to reference a node. A base block anchored with &defaults and referenced three times appears three times in the output, so a 40-line config can produce noticeably more JSON than you expected — the counter under the panels shows how many nodes the expansion added. An alias pointing at an anchor that has not been defined yet is an error rather than a guess, which also rules out the recursive structures YAML permits and JSON cannot express at all.

Why did all my comments disappear?

Because JSON has no comment syntax and never has. RFC 8259 defines six structural characters, three literal names and two scalar types, and none of them starts a comment — this is why .eslintrc and tsconfig.json needed the unofficial JSONC dialect, and why every attempt to add // to JSON has been refused. The count of removed comments is reported here rather than hidden, since in an infrastructure file the comments are often the only record of why a value is what it is.

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

Because you are reading two different versions of YAML. Under the 1.2 core schema nothing but true and false is a boolean; the 1.1 specification also resolved y, yes, on, n, no and off, and PyYAML, SnakeYAML and Psych still implement 1.1 by default. The famous casualty is the ISO country code for Norway — NO in an unquoted list becomes the boolean false — and the fix in your source file is a pair of quotes. Switch the schema selector to see both readings of the same document.

What happens to a date written in YAML?

It becomes a string, because JSON has no date type. YAML resolves 2026-08-09 to a timestamp and hands your program a date object; the JSON here holds "2026-08-09" and whatever reads it next gets characters. Every timestamp converted is listed in the report, which matters if the receiving code does arithmetic on the value rather than just displaying it.

How are | and > multi-line strings converted?

Both become ordinary JSON strings, with the folding already applied. A literal block written with | keeps its internal line breaks as \n; a folded block written with > has its single newlines turned into spaces and its blank lines kept as breaks. The chomping indicator decides the ending: | keeps one trailing newline, |- keeps none, |+ keeps all of them — a distinction that survives into the JSON string and is invisible until something compares two values.

Why does my file fail with an error about tabs?

Because YAML forbids tab characters in indentation, and this is the single most common reason a file that looks perfectly aligned refuses to parse. A tab may appear inside a value, but the whitespace that establishes structure must be spaces — the specification is explicit, and the error here names the line and the column of the offending tab rather than saying the document is invalid. Editors configured to insert tabs in .yml files cause almost all of these.

About YAML 1.1, YAML 1.2, and the gap between them

YAML 1.1 was published in 2005 and YAML 1.2 in 2009, with a maintenance revision, 1.2.2, arriving in 2021. The 1.2 rewrite had one headline goal — make JSON a strict subset — and achieving it meant narrowing the type resolution rules that 1.1 had made famous. Under 1.1 the plain scalars y, yes, on, n, no and off all resolve to booleans, a leading zero means octal, and a colon-separated number like 1:30 is a sexagesimal integer. Under the 1.2 core schema, none of that is true: only true and false are booleans and everything else stays a string. The catch is that the ecosystem never finished moving. PyYAML, SnakeYAML and Ruby's Psych still implement 1.1 semantics by default, so the same file genuinely means different things to different readers, and a converter that does not tell you which rules it applied is hiding the most important thing about your data.

The best-known consequence has a name. In a list of ISO 3166 country codes, unquoted NO for Norway is read as the boolean false by any 1.1 parser, which is how the “Norway problem” entered folklore. The same rule catches version numbers written 1.10, umasks written 0755, and MAC-address fragments. Every fix is the same: quote the scalar. That is also what the JSON to YAML page does automatically when it writes YAML, and why its output stays safe for a 1.1 reader.

Anchors are the other feature worth understanding before you convert. They exist so a config can say something once — a base job, a set of defaults, a volume mount — and reuse it, and a merge key folds that block into a mapping where explicit keys still win. JSON has neither, so the conversion inlines everything, and a file that was deliberately written to avoid repetition becomes the repetition it was avoiding. That is fine as machine input and unpleasant as something to maintain, so treat converted JSON as an artefact rather than a new source of truth. Once it exists, the JSON viewer is the quickest way to check the expanded shape, and the YAML validator is where to go when the source file will not parse in the first place.

Where the config is parsed

Everything happens in this tab: the YAML you paste is parsed by JavaScript on your machine and never uploaded or logged. Infrastructure files carry hostnames, bucket names and occasionally a secret that should not have been committed, and none of that leaves the browser here.