yq -o=json config.yaml prints a YAML file as JSON with mikefarah’s yq, the Go one that brew install yq installs. For this config.yaml:
name: deploy
on: push
region: NO
mode: 0755
released: 2026-10-15
version: 1.10
yq 4.54.1 prints:
{
"name": "deploy",
"on": "push",
"region": "NO",
"mode": 755,
"released": "2026-10-15",
"version": 1.10
}
The converter below gives the same, except that it writes 1.1: yq keeps a number’s spelling, and both read as the same number. Like the tool, yq follows YAML 1.2 here, so on and NO stay strings, 0755 is decimal (yq '.mode + 1' prints 756) and the date stays text. PyYAML, a YAML 1.1 parser, reads the same file as True, False, 493 and a date.
The flags
yq -o=json config.yaml # or -o json, --output-format=json
yq -o=json -I=4 config.yaml # 4-space indent; -I=0 prints one line per document
yq -o=json '.name' config.yaml # one value: "deploy"
yq -p=json -o=yaml data.json # JSON to YAML
The way back quotes less than you’d want
yq -p=json -o=yaml writes strings unquoted wherever YAML 1.2 allows it. For {"on":"push","region":"NO","debug":"off","mode":"0755"}:
on: push
region: NO
debug: off
mode: "0755"
yq reads that back correctly, but PyYAML and other YAML 1.1 readers turn on, NO and off into booleans. JSON → YAML in the tool quotes them: "on": push, region: "NO", debug: "off".
Several documents and merge keys
A file with --- between documents comes out as one JSON object after another, which isn’t one JSON value. yq ea -o=json '[.]' k8s.yaml collects them into an array, as the tool does.
With a merge key, yq 4.54.1 warns that --yaml-fix-merge-anchor-to-spec is false, and the warning matters. In
x-defaults: &defaults
restart: unless-stopped
services:
worker:
restart: "no"
<<: *defaults
the merge-key spec says the worker’s own restart wins, but yq prints "restart": "unless-stopped". Add --yaml-fix-merge-anchor-to-spec and it prints "no", as the tool does.
Which yq is this?
There are two. pip install yq, brew install python-yq and Debian’s yq package install kislyuk’s yq, a Python wrapper around jq with jq’s syntax: yq . config.yaml prints JSON, and -o=json fails with jq: Unknown option -o=json. yq --version tells them apart: yq (https://github.com/mikefarah/yq/) version v4.54.1 against yq 4.4.5. For this file the Python one prints "version": 1.1 and otherwise the same JSON.