How to convert YAML to CSV
Paste your YAML into the converter at the top of this page (or upload a .yaml/.yml file). The tool expects a top-level list of mappings — the most common shape for config exports — and produces a CSV where each list item is a row and each key is a column. Pick the delimiter (comma/semicolon/tab) and download. Runs entirely in your browser.
Nested mappings are flattened with dot notation (metadata.namespace becomes one column). Inline lists (ports: [80, 443]) are kept as JSON-stringified values. Going the other direction? See CSV to YAML.
YAML to CSV examples
Kubernetes pods
A common workflow: dump pod info with kubectl get pods -o yaml, post-process with yq, paste here.
- name: web-7d9f
namespace: production
status: Running
node: ip-10-0-1-23
restarts: 0
- name: api-5f4b
namespace: production
status: Running
node: ip-10-0-1-47
restarts: 2
- name: worker-b6c2
namespace: jobs
status: CrashLoopBackOff
node: ip-10-0-2-11
restarts: 14
Becomes:
name,namespace,status,node,restarts
web-7d9f,production,Running,ip-10-0-1-23,0
api-5f4b,production,Running,ip-10-0-1-47,2
worker-b6c2,jobs,CrashLoopBackOff,ip-10-0-2-11,14
GitHub Actions workflow jobs
Paste the jobs: map after running yq '.jobs | to_entries | map({name: .key, runs_on: .value."runs-on", needs: (.value.needs // [])})' against your workflow file.
- name: lint
runs_on: ubuntu-latest
needs: []
- name: test
runs_on: ubuntu-latest
needs: ["lint"]
- name: deploy
runs_on: ubuntu-22.04
needs: ["test"]
Generic config export
- service: auth
region: us-east-1
config:
timeout_ms: 5000
retries: 3
- service: billing
region: eu-west-1
config:
timeout_ms: 8000
retries: 5
Flattens to columns service, region, config.timeout_ms, config.retries.
Flattening nested YAML
The flattener walks one level deep. user: {name: Ada, email: ada@lovelace.io} becomes columns user.name, user.email. For deeper nesting (user.address.city), reshape with yq first:
yq '.[] | {id, name: .user.name, city: .user.address.city}' input.yaml
Inline lists are written as JSON-encoded strings — tags: [prod, web] becomes "[\"prod\",\"web\"]" in the cell. To get one row per tag, explode first with yq '.[] | . as $r | .tags[] | $r * {tag: .} | del(.tags)'.
How to convert YAML to CSV in Python, yq, or Ruby
Python (PyYAML + pandas) — json_normalize does the same dot-notation flattening as the converter above:
import yaml, pandas as pd
data = yaml.safe_load(open("input.yaml")) # never use load() on untrusted input
pd.json_normalize(data).to_csv("out.csv", index=False)
yq (the Go version) ships a CSV output mode:
yq -o=csv '.' input.yaml > out.csv
yq -o=csv '.[] | [.name, .namespace, .status]' pods.yaml > pods.csv
The Python yq (a jq wrapper) doesn’t support -o=csv — pipe through jq -r instead: yq -j '.' input.yaml | jq -r '.[] | [.name, .age] | @csv'.
Ruby:
require "yaml"; require "csv"
data = YAML.safe_load_file("input.yaml")
keys = data.flat_map(&:keys).uniq
CSV.open("out.csv", "w") { |csv| csv << keys; data.each { |r| csv << keys.map { |k| r[k] } } }
Common YAML-to-CSV problems
”YAML anchors/aliases not supported”
YAML lets you DRY up repeated blocks with &anchor and *alias:
defaults: &defaults
timeout: 30
retries: 3
- name: web
<<: *defaults
The converter doesn’t expand these — pre-process with yq 'explode(.)' first, which inlines anchors:
yq 'explode(.)' input.yaml > expanded.yaml
“Multi-document streams not supported”
Files with --- separators between documents (common for kubectl get all -o yaml) are split by the YAML spec into multiple docs. The converter only reads the first one. Split first:
yq 'select(documentIndex == 0)' input.yaml # first doc
yq -s '.' input.yaml # all docs as one list
The second form merges every doc into a single top-level list — paste that into the converter.
”Block scalars not supported”
Long strings written with | (literal) or > (folded) aren’t supported in this minimal parser:
- name: example
description: |
A multi-line
description
Convert block scalars to inline quoted strings first, or use the Python recipe above.
”Lists nested inside mappings”
A row with containers: [{image: nginx}, {image: sidecar}] doesn’t fit a flat CSV — one row, multiple containers. The converter throws a clear error. Either explode (one row per container) via yq or project a single container’s fields.
”Indentation errors”
YAML is whitespace-sensitive — mixing tabs and spaces, or indenting children inconsistently, breaks parsing. The error message includes the line number. Most editors highlight indent issues automatically.
When YAML doesn’t fit a flat CSV
YAML is a tree. CSV is a table. The mapping works when the tree is roughly tabular — a list of similar records. It breaks down when:
- Records have wildly different shapes — heterogeneous lists produce sparse CSVs with mostly-empty cells.
- Nesting is deep — flattening produces 30+ columns most of which are mostly null.
- Lists nest inside lists — there’s no obvious row boundary.
When the data really is tree-shaped, a flat CSV loses information. Two alternatives:
- Pre-flatten with
yqto project just the fields you need (.[] | {name, status}). - Convert to JSON first (
yq -o=json), reshape withjq, then use the JSON to CSV tool —jqis more powerful thanyqfor restructuring.
Privacy: nothing is uploaded
The YAML-to-CSV conversion runs entirely in your browser. Parsing happens in a small in-house YAML reader; the CSV is generated by PapaParse. No file ever reaches a server — verify in DevTools → Network. Useful when the YAML contains secrets, internal hostnames, or any data you wouldn’t paste into a public converter.
After converting, you might want to view the CSV, go the other direction with CSV to YAML, or convert similar formats with JSON to CSV.
Related tools
Convert any CSV file to a real .xlsx Excel workbook in seconds. Free, no signup, files never leave your browser.
Turn any .xlsx or .xls Excel file into a clean CSV. Pick the sheet, pick the delimiter, download. No upload.
Convert any Excel workbook (.xlsx or .xls) to a printable PDF in seconds. Pick the sheet, pick orientation, download. 100% private.
Convert any CSV file to a clean PDF table in seconds. Free, no signup, files never leave your browser.
Frequently asked questions
- How do I convert YAML to CSV?
Paste your YAML into the converter at the top of this page or upload a .yaml/.yml file. The tool flattens the top-level list of mappings into rows and writes a clean CSV. Click Download CSV or Copy to clipboard.
- How are nested keys handled?
Nested mappings are flattened with dot notation: a key like `metadata.namespace` becomes a single column. Inline lists (e.g. ports: [80, 443]) are kept as a JSON-stringified value inside one cell.
- What YAML subset does this support?
A pragmatic subset that covers config exports: top-level list of mappings (`- key: value` blocks), scalars (strings, numbers, booleans, null), one level of nested mappings, and `#` comments. Anchors/aliases, multi-document streams, and block scalars (`|`, `>`) aren't supported — convert them first with `yq` or `python -m yaml`.
- What if my YAML doesn't fit a flat CSV?
Some YAML — Kubernetes manifests with deeply nested specs, Ansible playbooks with task lists — doesn't map cleanly to a 2D table. The tool will either flatten one level (containers.0.image) or throw a clear error. Reshape the YAML with `yq` first if the structure is too deep.
- Can it handle Kubernetes or Ansible exports?
For simple list exports (e.g. `kubectl get pods -o yaml | yq '.items[] | {name: .metadata.name, status: .status.phase}'`) yes. For full multi-document Kubernetes manifests, run them through `yq` first to extract a flat list before pasting here.
- Does it handle comments?
Yes — `#` comments (full-line and trailing) are stripped during parsing. They don't appear in the CSV output.
- What about quoted strings with commas?
Quoted YAML strings (single or double) are preserved verbatim as cell values. PapaParse then re-escapes them on output per RFC 4180 — fields with commas, quotes, or newlines get wrapped in double quotes.
- Is my YAML uploaded?
No. Parsing and CSV generation run entirely in your browser. Your data never reaches a server. Verify in DevTools → Network.