gojq

A pure Go implementation of jq for querying and transforming JSON and YAML, usable as a CLI or embedded as a Go library.

Tool
Go
vv0.12.19
3,796stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
73/100Good
Development Activity76
Maintenance64
Community52
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
68/100Good
Architecture80
Code Quality82
Innovation80
Learning Curve30

gojq is a pure Go reimplementation of the jq command-line JSON processor, distributed as a single portable static binary with no C library dependency, installable via Homebrew, mise, or Docker. It parses jq’s query language and adds arbitrary-precision integer arithmetic, string indexing, and native YAML input/output, along with clearer parse-error and JSON-error messages that point at the exact offending token.

Beyond the CLI, gojq exposes its parser and interpreter as an importable Go package (gojq.Parse, gojq.Compile, Query.Run/Code.Run), letting applications embed jq-style querying directly, with functional options for injecting custom functions, module loading, environment variables, and iterator-based functions into the query runtime.

What You Get

  • A drop-in gojq CLI binary with no cgo or C library dependency, installable via Homebrew, mise, Zero Install, or Docker
  • Arbitrary-precision integer arithmetic for addition, subtraction, multiplication, modulo, and division, which upstream jq loses precision on
  • Native YAML input and output (--yaml-input/--yaml-output) alongside standard JSON handling
  • An embeddable Go library API (gojq.Parse, gojq.Compile, Query.Run, Code.Run) for compiling and running jq queries directly from Go code
  • Descriptive parse and JSON-input error messages with a caret pointing at the exact byte offset of the problem

Common Use Cases

  • Piping API responses or logs through gojq in shell scripts to filter, extract, and reshape JSON fields
  • Converting between JSON and YAML on the command line using the same familiar jq query syntax
  • Embedding jq queries inside a Go CLI or service so end users can supply their own transformation expressions at runtime
  • Processing very large integer identifiers (e.g. Snowflake/Twitter IDs) without losing precision, which the original C-based jq cannot guarantee

Under The Hood

Architecture gojq’s pipeline runs source text through a goyacc-generated parser (parser.go, regenerated from parser.go.y) into an AST of Query/Term nodes (query.go), which a dedicated compiler (compiler.go) walks to emit a stack-based sequence of code instructions with explicit scope tracking (scope_stack.go, stack.go). A separate execute.go interpreter runs that compiled *Code through an iterator-based model (iter.go, Iter) so results — including infinite streams and multiple emitted values — are pulled lazily rather than materialized upfront. The CLI itself lives in a distinct cli package (cli.go, run.go, flags.go, inputs.go) that wraps the library’s Query/Code API with argument parsing, encoders, and color output, keeping the importable gojq package free of CLI concerns.

Tech Stack Written in Go 1.24+ with a minimal dependency set — google/go-cmp for test assertions, itchyny/go-yaml for YAML I/O, itchyny/timefmt-go for time formatting, and mattn/go-isatty plus mattn/go-runewidth for terminal detection and width-aware output — with JSON encoding, numeric handling, and the lexer/parser otherwise hand-written or standard-library based. The Makefile drives goyacc to regenerate parser.go from parser.go.y, and GitHub Actions CI builds the binary and re-executes every shell example embedded in the README as a smoke test.

Code Quality The project carries an extensive suite of _test.go files alongside nearly every core source file (compiler_test.go, query_test.go, option_test.go, and more), using table-driven tests and go-cmp for structural diffing. Error types are explicit and typed — dozens of named error structs in error.go implementing a shared ValueError interface rather than bare string errors — and CI additionally treats the README’s own usage examples as executable tests, catching documentation drift. No linter configuration or coverage badge is present, but the typed-error discipline and test breadth are notably strong for a project of this size.

API Design The public library surface is deliberately small and composable — Parse, Compile, and Query.Run/Code.Run, each with a WithContext variant — with configuration expressed as functional options (WithModuleLoader, WithEnvironLoader, WithVariables, WithFunction, WithIterFunction) passed into Compile, letting callers extend the query language without forking the interpreter. The README documents this API directly with links to generated godoc, and the Iter/HaltError result contract is explained precisely enough that error handling is unambiguous, though requiring custom structs to be JSON round-tripped into any before querying is a real ergonomic wart the docs call out themselves.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search