Self-hosted service
JFryy/qq avatar
JFryy/qq

qq: jq syntax across a dozen config formats, with transcoding in one command

jq, but with many interoperable configuration format transcodings and interactive querying.

740 stars17 forksGoMIT

At a glance

What is it?
qq is a Go tool that applies jq queries to YAML, TOML, XML, HCL, CSV, Parquet and more, and converts between them in the same command. It borrows its query engine from gojq and adds an interactive REPL, and it ships as a single static binary or a Docker image.
Who is it for?
qq fits anyone who keeps configuration in several formats and wants one query language across them, or a Terraform or CI script that needs HCL or TOML turned into JSON without a bespoke converter. It does not fit a workflow that depends on jq edge behaviour, since the query engine is gojq rather than jq itself, nor a team that needs a guaranteed-stable CLI, given the project describes itself as a composition of other tools.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One command both queries and converts

qq is described as a multi-format transcoder and query tool powered by jq syntax, and the point of the project is stated plainly in the README: it lets you query and convert between configuration and data formats without needing separate tools for each one. The background section explains the motivation with a specific complaint about jq itself. The author found himself needing a bespoke tool for a format other than JSON, either a dedicated tool with JSON querying built in or a simple converter from a configuration format to JSON to pipe into jq. qq is the answer to that: one binary that reads a format, runs a jq-style filter, and writes a format. It also has an interactive REPL with autocomplete and a realtime rendering preview, so you can build a query by hand instead of guessing filter syntax in a shell loop.

The format list is broad, and two entries are read-only

The supported formats are enumerated in the README, and the read and write split matters if you are scripting against it. Read and write support covers .json, .yaml and .yml, .toml, .xml, .hcl and .tf, .csv, .tsv, .ini, .properties, .gron, .html, .jsonl with its .ndjson and .jsonlines aliases, .jsonc, .parquet, .msgpack and .mpk, .cbor, .avro, .base64 and .b64, and .txt or .text. Two formats are read-only: .proto and .env. The .env restriction is the one to remember, since environment files are a common source for the kind of flat key-value data people want to query, and being able to read them but not write them is a deliberate asymmetry rather than a bug. Format detection is automatic from the file extension, and the -i and -o flags override it explicitly, so a file with a misleading extension can still be handled.

Transcoding examples that read like a cheat sheet

The README's first block of examples covers the transcoding cases, and the pattern is identical in each: the jq filter, then the input file, then -o with the target format. YAML to JSON is qq '.' config.yaml -o json, TOML to YAML is qq '.' pyproject.toml -o yaml, CSV to Parquet is qq '.' data.csv -o parquet, and JSON to CBOR is qq '.' payload.json -o cbor. XML needs a filter that names the root, so it is qq '.root' config.xml -o toml. Terraform HCL to JSON is qq '.' infra.tf -o json, which the README notes is useful for scripting. Avro needs no output flag at all because the schema is embedded in the OCF file, so qq '.' events.avro is enough. Piping works too, for example cat file.msgpack | qq -i msgpack -o yaml, which is how you chain a conversion into another tool without touching the disk.

Streaming, slurp and exit status are the jq features people forget

Beyond transcoding, qq carries over the operational parts of jq that matter in shell scripts. Streaming mode uses the --stream flag and is described as identical to jq's, with extended support for JSONL, YAML, CSV, TSV and line-delimited formats, all emitting path-value pairs so large files can be processed without loading them whole. The --stream example in the README runs a select(length == 2) filter over large.json. Slurp mode uses -s to read multiple inputs into an array, so echo of two small JSON objects piped into qq -s 'map(.id)' returns both ids. Exit status uses -e, and the example pipes a JSON document into qq -e '.active' so a false result becomes a non-zero exit and the shell's && operator decides what happens next. These three flags are what make qq usable as a building block rather than only a viewer.

An interactive REPL with autocomplete and a live preview

The interactive mode is the feature that distinguishes qq from a plain converter, and the README flags it as one of the project's original contributions rather than something borrowed. It is invoked with the --interactive flag on a target file, for example qq . file.json --interactive. The description says the interactive mode provides a query builder with autocomplete and realtime rendering preview, so you see the result of the filter as you type it rather than after you press enter. The README notes that the usage examples emphasise interactive mode for demonstration, but that qq is designed for usage in shell scripts, which is the right way round: the REPL is where you find out what your filter should be, and the script is where the filter actually runs. The demo GIF in the docs directory shows the session.

Building it yourself and running it in a container

Installation covers the usual channels. The README lists brew install jfryy/tap/qq from Homebrew, yay qq-git from the AUR for Arch, a source build with make install that requires go 1.22.4 or newer, and a download from the releases page. There is also a Docker image at jfryy/qq on Docker Hub, with the quickstart shown as pulling the image and running it against piped JSON.

shell
docker pull jfryy/qq

The Dockerfile in the repository shows how the image is put together: a golang:1.25 builder stage that sets CGO_ENABLED=1, copies the source in, and builds with the version stamped into a linker flag at github.com/JFryy/qq/cli.Version, then a second stage based on gcr.io/distroless/static:nonroot that copies in the single binary and sets it as the entrypoint. The Makefile mirrors that with a build target, a test target that runs a shell script under tests plus go test with coverage, an install target that copies the binary into ~/.local/bin, and a docker-push target that builds for linux/amd64 and linux/arm64.

A composition of gojq, gron, fq and yq, and what that implies

The README is unusually candid about its origins. It says the project is arguably more of a composition of other projects than a truly original work, with glue code, some dedicated encoders and decoders, and the interactive mode being the original work. The acknowledgements name the pieces. gojq, a pure Go implementation of jq, powers the query engine. fq is a jq-like tool for querying binary formats. gron transforms JSON into discrete assignments that are easy to grep, and it shows up in the format list and in the git diff configuration. yq is the YAML counterpart tool. The go.mod lists the direct dependencies that follow from that design: gojq v0.12.18, cobra for the CLI, charmbracelet bubbletea, bubbles and lipgloss for the terminal interface, chroma for syntax highlighting, BurntSushi/toml, hashicorp/hcl and tmccombs/hcl2json, apache arrow for Parquet, hamba/avro, fxamacker/cbor, vmihailenco/msgpack, clbanning/mxj for XML, gopkg.in/ini.v1, fatih/color and mattn/go-isatty. The licence is MIT and the last push was on 2026-10-13, with v0.4.0 released on 2026-10-01.

Editorial conclusion

qq fits anyone who keeps configuration in several formats and wants one query language across them, or a Terraform or CI script that needs HCL or TOML turned into JSON without a bespoke converter. It does not fit a workflow that depends on jq edge behaviour, since the query engine is gojq rather than jq itself, nor a team that needs a guaranteed-stable CLI, given the project describes itself as a composition of other tools. Verify first that the gojq-backed engine handles the query you rely on, and check the read-only versus read-write format list before scripting against it.

Frequently asked questions

How do I install qq?

The README lists brew install jfryy/tap/qq for Homebrew, yay qq-git for the AUR, make install from source with go 1.22.4 or newer, and a download from the GitHub releases page. A Docker image is published as jfryy/qq.

Which file formats can qq read and write?

Read and write support covers JSON, YAML, TOML, XML, HCL and Terraform files, CSV, TSV, INI, properties, gron, HTML, JSONL and its aliases, JSONC, Parquet, MessagePack, CBOR, Avro, base64 and plain text. The README lists .proto and .env as read-only.

Does qq have an interactive mode?

Yes. The README describes an interactive REPL invoked with the --interactive flag, offering a query builder with autocomplete and a realtime rendering preview. It notes that the interactive mode is the original work in the project, alongside the glue code and some encoders.

Is qq the same as jq?

No. The query engine is powered by gojq, a pure Go implementation of jq, rather than jq itself, and qq adds transcoding between formats plus the interactive mode. The README credits jq, gojq, gron, fq and yq as inspirations and dependencies.

Official sources

  1. Issues
  2. JFryy/qq on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jfryy-qq.svg)](https://hysenlabs.com/projects/jfryy-qq)