Skip to main content

How to Format YAML: A YAML Formatter for Clean Indentation and Diffs

Format YAML with consistent spaces (not tabs), sort keys for stable diffs, and validate that it parses — straight from your browser, no upload.

Published By Li Lei
#yaml #formatting #devops #kubernetes #ci

How to Format YAML: A YAML Formatter for Clean Indentation and Diffs

YAML looks friendly until it bites you. There are no braces telling you where a block starts and ends, so the structure lives entirely in the whitespace at the front of each line. Get that whitespace wrong by a single column and your Kubernetes deployment fails, your GitHub Actions run dies on line 47, or your docker-compose.yaml silently nests a key under the wrong parent. A YAML formatter takes that fragile, hand-edited file and rewrites it with one consistent indentation, then confirms the whole thing actually parses before you commit.

This is a walk through what a formatter does, the indentation traps that catch people most often, and why running it locally matters when your config carries secrets.

Why YAML Indentation Breaks So Often

The single most important rule in YAML: indentation uses spaces, never tabs. The spec forbids tab characters as indentation outright. The trouble is that a tab and a run of spaces look identical in most editors, so a stray tab pasted from a terminal or inserted by an editor's auto-indent is invisible to you but fatal to the parser. The error you get back is the famously unhelpful "found character that cannot start any token," pointing at a line that looks perfectly fine.

Mixed indentation is the second trap. One block uses two spaces, the next uses four, and as long as each block is internally consistent the file still parses — but it parses into a structure you didn't intend, because YAML reads indentation depth, not a fixed step. A formatter solves both: it normalizes every line to a single consistent indent (two or four spaces, your choice), strips tabs entirely, and re-emits the document so depth is uniform everywhere.

The third habit worth naming is trusting old YAML 1.1 reflexes. Under 1.1, the bare words yes, no, on, and off coerce to booleans. The modern 1.2 spec treats them as plain strings, so a key like on: in a GitHub Actions workflow is a string under 1.2 but can turn into the boolean true in 1.1 tooling — quietly renaming your key. When in doubt, quote it: "on":.

What a Good Formatter Actually Does

Three jobs, in order:

  1. Re-indent. Parse the document, then serialize it back out with one consistent indent width. Tabs become spaces, ragged blocks become uniform.
  2. Sort keys (optional). Recursively reorder every map alphabetically. This is the secret to clean diffs — more on that below.
  3. Validate. If the input doesn't parse, you get the exact line number of the syntax error instead of a vague failure three steps later in your CI pipeline.

You can try all three on the YAML formatter. Paste, click Format, copy the result back. There's no CLI to install and no project config file to maintain, which is the friction that keeps people from reaching for yq or prettier --parser yaml on a quick one-off.

A Messy File, Reflowed

Here's the kind of YAML that lands in a pull request after a few hands have touched it — inconsistent indent, a tab hiding in one line, keys in random order:

name: deploy
on:
    push:
      branches: [main]
jobs:
  build:
   runs-on: ubuntu-latest
   steps:
        - uses: actions/checkout@v4
        - run: make build
env:
  NODE_ENV: production
  CACHE_DIR: /tmp/cache

Notice the push: block indented four spaces, runs-on: indented three, the steps: entries indented eight, and the env: map sitting at the bottom in no particular order. Run it through Format with a 2-space indent and Sort keys turned on, and you get this:

env:
  CACHE_DIR: /tmp/cache
  NODE_ENV: production
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: make build
name: deploy
on:
  push:
    branches:
      - main

Every block now steps in by exactly two spaces. The env keys are alphabetized, and the top-level keys (env, jobs, name, on) are sorted too. The flow sequence [main] was expanded to a block list. Most importantly, the formatter confirmed the document parses — if that hidden tab had been load-bearing, you'd have gotten a line number instead of clean output.

Sort Keys: The Trick for Stable Diffs

This is the feature DevOps teams fall in love with. Picture two engineers editing the same 300-line Kubernetes Deployment. One adds a field near the top, the other near the bottom, and because their editors serialized the map in different orders, the git diff shows forty lines of pure reordering on top of the two lines that actually changed. Reviewers can't see the real change for the noise.

Turn on Sort keys and run both files through the formatter before committing. Every map is reordered alphabetically and deterministically, so the only lines that appear in the diff are the ones that genuinely changed. The same trick stabilizes lockfiles, Helm values, and any generated config that tends to shuffle its key order between runs.

One caveat: sorting reorders map entries, but on re-serialization it drops the textual names of YAML anchors (&web) and aliases (*web) — the structural reference is kept and inlined, but if a downstream tool greps for the literal anchor name, format without Sort keys for that file.

Keep Secret-Bearing Config Local

I work on configs that hold database passwords and API tokens all the time, and the first thing I check on any "online YAML validator" is whether it POSTs my file to a server. Most do. That makes them a non-starter for a real docker-compose.yaml or a .env.yaml with live credentials — you'd be uploading secrets to a stranger's box just to check indentation.

The formatter here runs entirely in your browser tab. The parsing library is compiled to JavaScript and executes on your machine; your YAML is never uploaded, never logged, and never written into the URL. So you can paste the genuine file, confirm the indentation under services: actually parses, fix the offending line before docker compose up chokes on it, and close the tab knowing nothing persisted anywhere.

Where Formatting Fits Your Workflow

A formatter is most valuable at three moments: right before you commit a hand-edited config, right after a merge conflict leaves the indentation in a strange state, and the moment CI fails with a token error you can't eyeball. Two spaces or four is a team convention — pick one and let the tool enforce it so nobody argues about it in review again.

When you need to hand the same data to a system that wants JSON instead — an API payload, a structured log, a Terraform variable — convert it with the YAML to JSON tool rather than wrestling YAML's flow syntax into a single line by hand. Format for humans, convert for machines, and let the parser catch the typos either way.


Made by Toolora · Updated 2026-06-13