mrkeyoor.com_
Wed 23 Sept 00:37 UTC
Dev Toolsevaluationupdated 26 Aug 2026

yq review

yq is a command-line tool for reading, selecting, changing, merging, and converting YAML and other structured text formats. It brings a jq-like expression language to YAML, JSON, XML, CSV, TOML, HCL, properties, and related files, including in-place edits that try to retain YAML comments and style.

+28stars / 7d
Verdict

Our yq build finished in 31 seconds, but 1 of 4 Go test packages failed because an unknown extension defaulted to YAML instead of returning unknown, so pin the version and test format detection in automation. yq is still the first tool to try for readable YAML queries, merges, conversions, and in-place changes across platforms. Choose jq for exact JSON semantics, and do not use yq as a formatting-preserving round-trip editor without fixtures for your YAML style.

We ran it

Lab card: what happened when we ran yqScreenshot of yq (mikefarah.gitbook.io/yq)
Install✓ · 19s56 packages
Build✓ · 31s
Tests✗ · 9s3 passed · 1 failed of 4 (go test)
Repo546 files~48,355 lines of source · 1.7 MB · 8 CI workflows · Dockerfile · tests dir

Answers from our run

Does yq build from source?

Dependencies installed in 19 seconds (56 packages), and the build succeeded in 31 seconds. We cloned commit c14f446 into a clean Debian container with 3 CPUs and no project-specific setup.

Do yq's tests pass?

Not all of them: 3 of 4 passed and 1 failed when we ran the project's own test command (go test). Some failures need services or credentials a bare container does not have.

Who should not use yq?

Anyone requiring complete jq compatibility: the README explicitly says yq does not support everything jq does.

What are the alternatives to yq?

jq, kislyuk yq, gojq. Our yq build finished in 31 seconds, but 1 of 4 Go test packages failed because an unknown extension defaulted to YAML instead of returning unknown, so pin the version and test format detection in automation.

Setup5/5Single binaries and many packages; no service or credentials required
Docs5/5Extensive operator pages, recipes, format guides, and examples
Community5/515,874 stars with releases and issue activity in the same week
Maturity4/5Broad v4 feature set, with active format and expression edge cases

Discussed on

  1. hnyq: command-line YAML, JSON, XML, CSV and properties processor224 points
  2. hnYq is a portable command-line YAML processor6 points
  3. hnYq: A portable command-line YAML processor5 points
  4. hnYq – a lightweight and portable command-line YAML, JSON and XML processor4 points

Who it’s for

Developers and operators editing YAML in shell scripts, CI jobs, and deployment pipelines.
Teams converting among YAML, JSON, XML, CSV, TOML, HCL, properties, and INI without a custom program.
jq users willing to learn the differences in yq's expression language.
Repository maintainers who need targeted in-place changes while retaining most YAML comments and formatting.
Cross-platform users who want one downloadable Go binary.

Who it’s NOT for

Anyone requiring complete jq compatibility: the README explicitly says yq does not support everything jq does.
Formatting-sensitive YAML round trips where byte-level style must stay untouched: the README acknowledges whitespace issues, and issue 2819 reproduces broken indentation for a single-quoted multiline scalar.
Pipelines that depend on unknown filename extensions being reported as unknown: our test run expected unknown for file.unknown, while the function returned yaml.
Snap users needing direct root-file access: strict confinement requires piping through sudo and using a separate write-back step.
Users relying on the tz operator in the stock Alpine container image: the installation notes say timezone data is absent unless you add tzdata.
Scripts assuming missing keys behave exactly like jq inside every conditional: issue 2782 reports that select, and, and or can drop a missing key instead of collecting null.

Setup reality

Our Go install succeeded in 19 seconds and fetched 56 packages. The build succeeded in 31 seconds. Tests finished in 9 seconds with 3 passed and 1 failed out of 4; the failure concerned format detection for an unknown filename extension.

Normal use is easier than source development: download a platform binary or install through Homebrew, snap, winget, Chocolatey, Go, Docker, Podman, Nix, or another package manager. No account or credential is required. In-place writes still need filesystem permission and a backup strategy.

Packaging changes behavior at the edges. The snap is strictly confined from root files. The container runs as a non-root yq user, needs a mounted working directory, and omits timezone data by default. Podman with SELinux needs the :z shared-volume flag.

yq turns structured-file edits into shell-sized commands

The yq README shows the basic appeal in one line: read .a.b[0].c from YAML with syntax familiar to jq users. The same expression language can update a file in place, select an array item, merge several documents, pull values from environment variables, or convert among YAML, JSON, XML, CSV, TOML, HCL, properties, and INI. That removes a surprising amount of throwaway Python, Ruby, or JavaScript from build scripts.

A downloadable Go binary keeps the execution model simple. There is no daemon, user account, language runtime, or remote service. The repository was 1.7 MB with 546 files in our checkout, and official binaries cover common Linux, macOS, and Windows architectures. Homebrew, snap, winget, Chocolatey, Docker, Podman, and go install provide other routes. This portability is yq's strongest practical advantage over a collection of format-specific scripts.

jq-like syntax is useful, but yq is not jq

Existing jq knowledge transfers to paths, pipes, selections, assignments, reductions, and many functions. It does not transfer perfectly. The README says yq does not yet implement everything jq does. Scripts copied from a JSON pipeline should be checked against the operator documentation and representative YAML, especially where missing nodes, tags, aliases, or multi-document streams change evaluation.

Issue 2782 gives a precise compatibility trap in version 4.53.3. Collecting a missing key normally produces an array containing null, but inside select, and, or or, the key can disappear and change the result. The report compares this with jq's behavior. A configuration gate built around optional fields could therefore select the wrong documents without producing a syntax error. Add fixtures for absence, null, false, and empty collections.

What happened when we ran it

Our sandbox installed commit c14f446 in 19 seconds and fetched 56 Go packages. The build succeeded in 31 seconds inside a fresh unprivileged Debian container with 3 CPUs and 8 GB of RAM. The project has a Dockerfile, 8 CI workflow files, and a tests directory. No secrets or network services were needed after dependencies had been resolved.

Go tests finished in 9 seconds with exit 1. Three packages passed: the main module, cmd, and pkg/yqlib. The test package failed TestFormatStringFromFilename. For file.unknown, FormatStringFromFilename returned yaml; the assertion expected unknown. That is a concrete format-detection mismatch, not a general parser or expression failure.

Only 4 package results appeared in our supplied summary, so the 3 passing results should not be inflated into a claim about every documented operator and format. The failure matters most to code that trusts automatic detection from filenames. For stdin or ambiguous extensions, the README already recommends the -p input-format flag. Explicit -p yaml, -p xml, or another known format is safer in automation than relying on a filename guess.

In-place editing preserves meaning better than exact presentation

YAML comments, anchors, aliases, tags, and style carry information that a simple JSON conversion loses. yq understands and can manipulate these features, and the README says in-place updates keep formatting and comments while acknowledging whitespace issues. That is useful for changing an image tag in a human-maintained manifest. It is not a promise that parse and print will reproduce every byte. Review diffs before committing automated rewrites.

Two open reports show the boundary. Issue 2819 says a single-quoted multiline scalar ending in a blank line loses the expected indentation when passed through yq .. Issue 2797 says some UTF-8 characters cause loaded multiline text to be emitted as a quoted single line with escaped newlines. Both concern valid content whose presentation matters to downstream tools or reviewers.

Package choice changes permissions and timezone behavior

The standalone binary has the fewest surprises. Snap uses strict confinement, so it cannot directly read root-owned files; the README shows piping privileged input into yq and writing through sponge or a temporary file. The container image runs as a non-root user. That is a sound default, though bind-mounted files must be readable and writable by the container user when -i is used.

Timezone operations require another container adjustment. The Alpine image omits timezone data, and the documented fix adds tzdata in a derived image. Podman on an SELinux host needs :z on the mounted working directory. These are packaging constraints rather than yq-language flaws, yet each can turn a correct expression into an access error or missing-timezone failure. Put the exact install form in CI documentation.

Version 4.53.6 is current, with active edge-case repair

Release 4.53.6 shipped on 2026-08-20 with a release-build fix, a line-wrapping repair, and dependency updates. The repository was pushed on 2026-08-25. It had 15,874 stars and 285 open issues and pull requests when fetched. Current pull requests addressed file-descriptor closing, integer overflow, missing keys, and output formatting, which shows maintenance continuing beyond the latest tag.

yq belongs in a developer's shell toolbox because it makes common YAML work short and readable while covering several neighboring formats. Its limits are equally concrete: partial jq compatibility, packaging-specific permissions, and imperfect style round trips. For JSON-only work, jq remains the reference. For YAML automation, yq wins when you pin a release, specify ambiguous formats, and keep golden-file tests around important edits.

Alternatives

ProjectWhat it isPick it when
jqThe standard command-line filter language and processor for JSON.pick this instead when your data is JSON and exact jq semantics or ecosystem compatibility matters.
kislyuk yqA Python command-line wrapper that converts YAML and other formats for processing by jq.pick this instead when you specifically want the real jq engine underneath YAML conversion and accept a Python-based tool.
gojqA pure Go implementation of jq with library and command-line interfaces.pick this instead when a Go-native jq implementation and JSON processing are the main requirements.

What people are saying

  1. [github-trending] mikefarah/yq

Sources

  1. yq README
  2. yq operator documentation
  3. yq 4.53.6 release
  4. Missing-key selection issue 2782
  5. UTF-8 multiline output issue 2797
  6. Single-quoted multiline indentation issue 2819

More dev tools reviews

crabbox · asdf · discord.js · h4cker · bend · 100-exercises-to-learn-rust · the whole board →