FIRST CH TOOLS / 20 JSON ⇄ YAML
JSON ⇄ YAML Converter & Syntax Formatter
Paste into either box and it is converted to the other format as you type. Pick the indent width and quoting style to reformat, and syntax errors are pinpointed by line and column with an explanation of what is wrong. Made for reading docker-compose and GitHub Actions config the other way round, and for turning API responses into config files.
Type in either box and the other one follows
Nothing you paste leaves the browser — the YAML parser and writer are implemented on this page, with no external library. Loading a file only reads it locally; it is never uploaded. Directly callable via URL parameters: /en/json-yaml/?yaml=a%3A%201 / /en/json-yaml/?json=%7B%22a%22%3A1%7D&indent=4
What tends to break when you convert
Tabs cannot be used for indentation
web: → image: nginx # ← the YAML spec forbids tabs for indenting
YAML only accepts spaces for indentation. When an editor's auto-indent inserts a tab, different parsers report the error in different places, which makes it hard to find. This tool points at the exact line and column where a tab is used for indenting.
yes / no / on / off can become booleans
country: NO # Norway's country code → true/false in some parsers enabled: yes # true, not the string "yes" on: push # a GitHub Actions key
YAML 1.1 treats these as booleans; YAML 1.2 treats them as strings. Because the meaning depends on the library reading the file, it is known as the "Norway problem" — the country code NO turning into false. This tool follows YAML 1.2 and keeps them as strings, but warns you about every value affected. Quote them, as in "yes", if they must stay text.
0755 is decimal 755, not octal
mode: 0755 # → 755 (this is not an octal literal) mode: 0o755 # → 493 (the YAML 1.2 way to write octal) mode: "0755" # → stays a string
Always quote values whose leading zero carries meaning — file permissions, postcodes, phone numbers, invoice numbers. Left unquoted they become numbers with the leading zero gone.
12:30 becomes 750 in some parsers
start: 12:30 # base-60 integer in YAML 1.1 → 12*60+30 = 750 start: "12:30" # stays a string ports: - 8080:80 # not a valid base-60 form, so it stays a string
YAML 1.1 has sexagesimal (base-60) integers, so a value like 12:30 turns into a number. Quote times and versions.
Values containing : (colon + space) or # need quotes
title: Heading: note # error (it looks like two keys) title: "Heading: note" # fine note: 100% done #left # → "100% done", and #left becomes a comment url: http://example.com # fine — the colon is not followed by a space
YAML only sees a key separator when the colon is followed by a space or the end of the line, and it only starts a comment at a # preceded by a space — so a#b stays a plain string.
Values starting with * or & need quotes too
include: *.js # error (read as a reference to an anchor named .js) include: "*.js" # fine
&name is an anchor (label this node) and *name is an alias (refer to a labelled node). Quote glob patterns and wildcards when they are values.
| and > mean different things for multi-line strings
literal: | # keep the line breaks (good for shell scripts) echo one echo two folded: > # fold line breaks into spaces (good for prose) this line and this one join up strip: |- # drop the final newline keep: |+ # keep the trailing blank lines
The trailing - and + are called chomping indicators, and they decide whether the final newline is kept. The default keeps exactly one. When writing YAML, this tool picks | or |- depending on whether the string ends with a newline.
Anchors, aliases and merge keys have no JSON equivalent
defaults: &defaults adapter: postgres pool: 5 development: <<: *defaults # splice the contents of defaults in here database: dev
JSON has no references, so the expanded result is written out and the content is duplicated. The merge key << is weaker than keys written explicitly in the same mapping, so an explicit key wins on a clash. Whenever this expansion happens, the tool says so in the syntax check.
Duplicate keys usually do not raise an error
image: nginx ports: ["80:80"] image: httpd # the later one wins and the first is silently lost
It is invalid per the spec, but most libraries quietly overwrite with the later value. It happens easily as a long config file grows, and it is hard to spot. This tool finds duplicate keys and warns about them.
JSON has no comments
{
// conventionally used in files like tsconfig.json
"strict": true, // ← the trailing comma is invalid too
}
Comments and trailing commas are not part of the JSON spec. This tool reads them, converts, and tells you — a converter that refuses real-world config files is not much use. Going the other way, comments written in YAML cannot be kept in JSON, so they are dropped.
Large integers lose digits
id: 12345678901234567890 # → becomes 12345678901234567000 id: "12345678901234567890" # → kept exactly, as a string
Both JSON and YAML normally read numbers as double-precision floats. Only values up to 2^53 (about 9.007 quadrillion) are exact; larger IDs have their low digits changed. Keep values such as Snowflake IDs as strings. This tool warns about every number affected.
YAML features supported: multiple documents (---), block mappings and sequences, flow style ([…] {…}), quoted scalars (multi-line, with escapes), block scalars (| > with chomping and explicit indent), anchors, aliases and merge keys, tags (!!str !!int !!float !!bool !!null !!binary) and comments. Not supported: the explicit ? key notation — since JSON keys are strings, rewrite it in the ordinary form.
How to Use
- Paste into either boxJSON on the left produces YAML on the right, and YAML on the right produces JSON on the left. You can also drag a config file onto either box.
- Choose the formattingSwitch the indent width, the quoting style and the key order. To tidy a file up without changing format, press "Format" above that box.
- Check the result and copySyntax errors are shown with their line and column. Anything whose meaning may change — tab indentation, 0755, yes, duplicate keys — appears in the warnings.
About This Tool
JSON and YAML describe the same data structures — mappings, sequences and scalars — with different notation. JSON marks structure with brackets and quotes, which suits machines; YAML marks it with indentation, which suits people. Config files gravitate to YAML while APIs speak JSON, and the boundary between them is where you need to convert.
YAML is a superset of JSON, so any valid JSON is already valid YAML (flow style is exactly JSON's notation). The reverse is not true. YAML has comments, anchors, multiple documents and timestamps with no JSON counterpart, so converting YAML to JSON always loses something. Rather than dropping those quietly, this tool reports them: comments removed, aliases expanded, multiple documents merged into an array.
Syntax errors come with a line and a column. The message from the browser's own JSON.parse differs between engines, and so does the way the position is reported. Here both JSON and YAML are parsed by hand, so every browser shows the same position and the same explanation. Two lines either side of the error are quoted, with ^ marking the column.
YAML has an unusual number of ways to parse fine but mean something else. Tab indentation, 0755 becoming decimal 755, yes and NO becoming booleans (the Norway problem), 12:30 becoming 750 in base 60, duplicate keys silently overwriting each other — the tool raises all of these every time it converts. The "YAML pitfalls" tab collects them with examples.
It also reads the JSON people actually have. JSON with comments (as in tsconfig.json), JSON with a trailing comma, JSON with single quotes or unquoted keys — all are read and converted, with a note that they are not valid JSON. Telling you what to fix is more useful than refusing to parse.
When writing YAML, the tool picks forms that cannot change meaning. Strings that another parser could read as a different type — yes, 0755, 12:30, 2026-08-12 — plus strings with leading or trailing spaces and strings starting with - or * are quoted automatically. Strings containing newlines become | blocks, unless the exact text could not be restored that way (trailing spaces on a line, for instance), in which case they fall back to "…".
Numbers are handled as double-precision floats. Integers are exact up to 2^53 (about 9.007 quadrillion); beyond that the low digits change, so those values are flagged. .inf and .nan do not exist in JSON and become null.
From AI Agents
This conversion logic is also available as the json_to_yaml and yaml_to_json tools of the MCP (Model Context Protocol) server @first-ch/tools-mcp, so an AI agent can call it directly without a browser — including reading and writing files by path. See Using these tools from AI agents for setup details.
Setup
claude mcp add firstch-tools -- npx -y @first-ch/tools-mcp
Examples
# JSON to YAML (indent 2, quotes only where needed)
json_to_yaml(text='{"name":"web","ports":["80:80"]}')
# YAML to JSON, minified
yaml_to_json(text="name: web\nports: [80:80]", indent=0)
# Read a config file, convert it, write it somewhere else
json_to_yaml(path="/tmp/config.json", outputPath="/tmp/config.yaml", indent=4)
# Just check the syntax (returns the error line/column and any warnings)
yaml_to_json(path="/tmp/docker-compose.yml")
Other Tools
- 01Batch Image → WebPWebP Converter
- 02White Background RemoverWhite BG Remover
- 03WCAG Contrast CheckerContrast Checker
- 04Character CounterCharacter Counter
- 05llms.txt Generatorllms.txt Generator
- 06JSON-LD GeneratorJSON-LD Generator
- 07Markdown → PDFMD → PDF
- 08OGP Meta Tag WizardOGP Wizard
- 09Favicon GeneratorFavicon Generator
- 10TikTok PublisherTikTok Publisher
- 11Encoding & Line Ending ConverterEncoding Converter
- 12Batch Image → AVIF + pictureAVIF Converter
- 13Test Data GeneratorTest Data Generator
- 14Marp Markdown → SlidesMarp Slides
- 15Text & Code Diff CheckerDiff Checker
- 16Cron Explainer & Next RunsCron Explainer
- 17Base64 & Data URI EncoderBase64 & Data URI
- 18URL Parameter Editor & UTM BuilderURL Parameters
- 19HTML Entity Escape & UnescapeHTML Escape
- 21PX ⇄ REM / EM ConverterPX ⇄ REM / EM 単位変換
- 22Color Converter & AlphaColorコード変換&アルファ透過
- 23MD5 / SHA-256 Hash Generatorハッシュ生成
- 24JWT Decoder & Expiry CheckerJWTデコーダー&有効期限チェッカー
- 25User-Agent ParserUser-Agent解析&デバイス判定
- 26UUID & ULID GeneratorUUID (v4) & ULID 一括生成
- 27Aspect Ratio Calculatorアスペクト比計算&サイズ算出