How to Install yq on Debian: A Portable YAML, JSON and XML Processor

yq is a portable, dependency-free command-line processor for YAML, JSON, XML, and more. Written in Go by Mike Farah, it does for YAML what jq does for JSON: you give it an expression and a document, and it queries, transforms, and rewrites structured data with a concise, jq-like syntax.

This is an important distinction to get right. There are two popular tools named yq. One is a thin Python wrapper around jq; the other — the one packaged here and the one most tutorials assume — is Mike Farah’s standalone Go binary. This guide covers the Go version, whose expression syntax looks like yq '.a.b' file.yaml and which ships as a single static executable with no runtime dependencies.

Debian does not carry an up-to-date yq in its official repositories, and the version that is available can lag well behind upstream. The unofficial deb.griffo.io repository provides a current .deb, so you can install yq with apt and keep it fresh through ordinary system upgrades.

What Makes yq Special?

  • 📄 Multi-format — reads and writes YAML, JSON, XML, TOML, CSV/TSV, and properties files
  • 🔧 jq-like expressions — a familiar path syntax for querying and transforming documents
  • ✏️ In-place editing — the -i flag updates a file directly while preserving structure
  • 💬 Comment preservation — keeps YAML comments intact through most edits
  • 🧩 Merge and combine — deep-merge multiple documents or files with a single expression
  • 📦 Single static binary — one Go executable with no interpreter or libraries to install
  • 🔁 Format conversion — convert YAML to JSON and back with -o output flags
  • 🗂️ Multi-document aware — handle YAML streams containing several --- documents

Why Use the deb.griffo.io Repository?

The deb.griffo.io repository makes yq painless to manage on Debian:

  • Easy installation and updates through the APT package manager
  • Automatic dependency management handled by Debian packaging
  • Always tracks upstream releases rather than the stale versions in the archive
  • No compiling from source or manual binary downloads to keep current
  • Works across supported Debian releases including Bookworm, Trixie, and Sid

Prerequisites

Before you begin, make sure you have:

  • A Debian-based system (Bookworm 12, Trixie 13, or Sid)
  • sudo privileges
  • curl installed (sudo apt install curl if needed)

Step 1: Add the deb.griffo.io Repository

Add the signing key and repository with these commands:

# Create the keyrings directory
sudo install -d -m 0755 /etc/apt/keyrings

# Download and install the repository GPG key
curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg

# Add the repository (auto-detects your distro codename)
echo "deb [signed-by=/etc/apt/keyrings/deb.griffo.io.gpg] https://deb.griffo.io/apt $(lsb_release -sc 2>/dev/null) main" | sudo tee /etc/apt/sources.list.d/deb.griffo.io.list > /dev/null

# Update the package list
sudo apt update

What each command does:

  1. Keyrings directory — creates /etc/apt/keyrings with correct permissions for the key
  2. GPG key — fetches and de-armors the repository signing key so APT can verify packages
  3. Repository entry — adds the source, with lsb_release -sc filling in your Debian codename
  4. Package list — refreshes APT so yq becomes installable

Step 2: Update the Package List

If you skipped the last command above, run it now:

sudo apt update

Step 3: Install yq

Install yq with a single command:

sudo apt install yq

This installs the yq Go binary and registers it on your PATH.

Step 4: Verify the Installation

Confirm the version to make sure you have Mike Farah’s Go build:

yq --version

You should see output like:

yq (https://github.com/mikefarah/yq/) version v4.44.3

The mikefarah/yq URL in the version string confirms you are running the Go implementation and not the Python wrapper.

Getting Started with yq

The examples below use a small sample file. Create it first:

cat > config.yaml <<'EOF'
service:
  name: web
  port: 8080
  replicas: 3
  tags:
    - frontend
    - public
database:
  host: db.internal
  port: 5432
EOF

Reading Values

Query a document with a path expression, exactly as the task suggests:

# Read a single value
yq '.service.name' config.yaml
# -> web

# Read a nested value
yq '.database.port' config.yaml
# -> 5432

# Read the first element of a sequence
yq '.service.tags[0]' config.yaml
# -> frontend

# Pull every service tag
yq '.service.tags[]' config.yaml

Editing In Place

The -i flag writes changes back to the file while keeping formatting and comments:

# Change a scalar value
yq -i '.service.port = 9090' config.yaml

# Add a new key
yq -i '.service.owner = "platform-team"' config.yaml

# Append to a sequence
yq -i '.service.tags += ["cached"]' config.yaml

# Delete a key
yq -i 'del(.database.host)' config.yaml

Converting Between Formats

yq converts between formats with the output (-o) and input (-p) flags:

# YAML to JSON
yq -o=json '.' config.yaml

# JSON back to YAML
yq -p=json -o=yaml '.' data.json

# Read an XML document as YAML
yq -p=xml '.' pom.xml

# Pretty-print compact JSON as YAML
cat data.json | yq -p=json -o=yaml

Filtering and Transforming

yq supports jq-style operators for selection and construction:

# Select mapping keys where a condition holds
yq '.service | select(.replicas > 2)' config.yaml

# Build a new object from existing fields
yq '{"name": .service.name, "port": .service.port}' config.yaml

Merging Documents

Deep-merge two files, letting the second override the first:

yq '. *= load("override.yaml")' config.yaml

# Or merge a stream of documents into one
yq eval-all '. as $item ireduce ({}; . * $item)' base.yaml patch.yaml

The * operator performs a recursive merge, which is handy for layering environment-specific overrides on top of a base configuration.

Keeping yq Updated

As a managed package, yq updates with the rest of your system:

sudo apt update && sudo apt upgrade

This keeps the yq binary current alongside your other Debian packages.

Other Tools from deb.griffo.io

The repository packages many complementary tools for Debian:

  • DuckDB — an in-process SQL engine for querying data files
  • Nushell — a shell built around structured data
  • fzf — a fuzzy finder that pairs well with piped yq output
  • just — a command runner for wrapping repetitive yq recipes

Troubleshooting

GPG or Key Errors

If APT reports the repository is not signed, re-add the key:

sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg
sudo apt update

Package Not Found

If APT cannot find yq:

  1. Run sudo apt update again to refresh the index
  2. Confirm your release is supported (Bookworm, Trixie, or Sid)
  3. Inspect the source entry: cat /etc/apt/sources.list.d/deb.griffo.io.list

Wrong yq Installed

If your expressions fail with syntax errors, you may have the Python yq (a jq wrapper) from pip shadowing the Go binary. Check which one is first on your PATH:

yq --version
which -a yq

The version string should contain github.com/mikefarah/yq. If it does not, remove the Python package (pip uninstall yq) or adjust your PATH so the APT-installed Go binary at /usr/bin/yq takes precedence.

Uninstalling

To remove yq:

sudo apt remove yq

To remove the repository as well:

sudo rm /etc/apt/sources.list.d/deb.griffo.io.list
sudo rm /etc/apt/keyrings/deb.griffo.io.gpg
sudo apt update

Conclusion

yq brings the ergonomics of jq to YAML, XML, and every other structured format you deal with in configuration files and CI pipelines. As a single static Go binary, it is fast, portable, and scriptable. On Debian, the deb.griffo.io repository gives you a current build via apt install yq and keeps it up to date with your usual upgrades.

Whether you are patching Kubernetes manifests, converting config formats, or merging environment overlays, yq is a tool you will reach for constantly. Install it, create the sample file above, and try a few expressions to get a feel for the syntax.

Resources


Disclaimer: The deb.griffo.io repository is an unofficial community project and is not affiliated with the official Debian or Ubuntu projects, or with the upstream yq project.