The pioneer. jq parses JSON, applies a query, emits JSON. Its filter syntax (.foo[], map, select) became the lingua franca for the others.
yq — same syntax, all four formats
Mike Farah's yq applies jq's filter language to YAML, JSON, TOML, XML, and CSV. yq -p toml -o yaml file.toml reads TOML and emits YAML. Best general-purpose conversion tool.
dasel — selector across many formats
dasel uses a unified selector syntax (.config.server.port) and supports JSON/YAML/TOML/XML/CSV. Lighter than yq for simple lookups; comparable for conversions.
gron — flatten JSON for grep
gron turns nested JSON into one assignment per line: json.users[0].name = "Pippa";. Then grep works the way you expect on JSON. gron --ungron rebuilds the original. Surgical for finding-then-extracting fields in deeply nested API responses.
Principle: learn jq's filter language once; reuse it via yq for YAML/TOML. The investment pays off across config audit, log spelunking, and CI pipeline glue. The minute you reach for Python to massage a YAML file, you've probably forgotten yq exists.
# Find all replicas across multi-document YAML
yq '.. | select(has("replicas")) | .replicas' deploy/*.yaml
# Filter PR JSON for open ones with a label
gh pr list --json number,title,labels | \
jq '[.[] | select(.labels[]?.name == "ready-for-review")]'
# Convert pyproject.toml [project] block to JSON
yq -p toml -o json '.project' pyproject.toml
dasel — quick lookups·bash
# Get a value
dasel -f config.yaml '.server.port'
# Set a value (in place)
dasel put -f config.yaml -v 9000 '.server.port'
# Convert via -r/-w flags
dasel -r yaml -w json < config.yaml > config.json
gron — grep deeply nested JSON·bash
# Flatten
gh api repos/cwk/foo | gron | head
# json.full_name = "cwk/foo";
# json.private = false;
# json.owner.login = "cwk";
# Find every URL field in the response:
gh api repos/cwk/foo | gron | grep '_url'
# Edit the gron output and ungron back to JSON
gh api repos/cwk/foo | gron > flat.txt
# (edit flat.txt)
gron --ungron < flat.txt > modified.json
Take a real config (a pyproject.toml, an Ansible inventory, a Kubernetes manifest). Convert it to each of the other three formats with yq. Diff the results. Notice what gets lost (comments, key order in some round-trips). Save the conversion incantation you used most often as a shell function in your dotfiles.
Progress
Progress is local-only — sign in to sync across devices.