gojq is a free, open source frameworks & platforms project written in Go and released under MIT. It has 3,804 GitHub stars, 154 forks and 18 open issues, and was last pushed 23 hours ago. On this registry it ranks #40 of 54 tracked projects in Frameworks & Platforms, with 5 head-to-head comparisons available.

What is gojq?

gojq is a pure Go implementation of the jq command-line JSON processor, built for Go developers and shell users who want jq's query language without jq's C dependencies.

What it is

gojq is a reimplementation of the jq command written in the Go language. It lives in the Go ecosystem, published as github.com/itchyny/gojq, and ships both as a standalone CLI tool and as a library that can be embedded directly into Go products. Because it is written purely in Go, it is completely portable: it does not depend on the C standard library, so the availability of math functions does not vary with the host system, and it does not depend on an external regular expression library, which keeps build scripts simple.

The concrete thing it replaces is the original jq binary from the jqlang project. That matters in cross-compilation, static binary, container, and Windows build pipelines where pulling in a C toolchain or a system-provided regex library is awkward or impossible. It also matters for Go applications that need jq-style JSON querying inside the process rather than by shelling out to an external binary, and for workloads where jq's floating-point conversion silently destroys large integer values.

Key capabilities

  • Runs jq expressions from the shell: .foo, .a.b, .[] | .id, computed object keys like {(.id): .["10"].b}, and update operators such as .a += 1 | .b *= 2.
  • Supports the ?// destructuring alternative operator, as in . as {$a} ?// [$a] ?// $a | $a.
  • Performs arbitrary-precision integer calculation: echo '{"foo": 4722366482869645213696}' | gojq .foo keeps the full precision of large numbers where jq would lose it.
  • Handles nanoseconds in date and time functions, deals with %f in strftime and strptime, parses timezone offsets in fromdate and fromdateiso8601, and supports timezone name and offset with %Z and %z in strptime.
  • Adds string indexing with "abcde"[2], correct handling of files with no trailing newline, and an @base64d that accepts a binary decoded string.
  • Installs through many channels: brew install gojq, mise use -g gojq@latest, 0install add gojq https://apps.0install.net/utils/gojq.xml, go install github.com/itchyny/gojq/cmd/gojq@latest, and the Docker images itchyny/gojq or ghcr.io/itchyny/gojq.
  • Embeds as a Go library, so JSON query logic can live inside an application rather than in a subprocess.

Who uses it and how

  • Go teams that embed gojq as a library to run jq expressions against JSON inside their own products, avoiding an external process dependency.
  • Cross-platform and container build pipelines that need jq syntax on systems where a C toolchain or system regex library is unavailable, running it via docker run -i --rm itchyny/gojq.
  • Workstations and CI runners that install it through Homebrew, mise, or Zero Install and invoke it exactly as they would invoke jq.
  • Data pipelines handling identifiers or counters larger than 64-bit floating point can represent, relying on the arbitrary-precision integer support to avoid silent truncation.
  • Log and event processing that needs nanosecond timestamps and explicit timezone offset parsing from JSON payloads.

Getting started

Install with brew install gojq, mise use -g gojq@latest, 0install add gojq https://apps.0install.net/utils/gojq.xml, or go install github.com/itchyny/gojq/cmd/gojq@latest. To run it without installing anything, use docker run -i --rm itchyny/gojq or docker run -i --rm ghcr.io/itchyny/gojq.

How it compares

Against jq, the tool it reimplements, gojq trades behavioural exactness for portability: it is written purely in Go, so it compiles and runs where jq's C standard library and regex dependencies make builds complex, and it keeps arbitrary-precision integers that jq loses during calculation. It is also the only one of the two that can be embedded as a library in a Go program. That portability costs the object key ordering that jq preserves.

When to use it — and when not to

Choose gojq for portable builds, embedded use in Go, and any pipeline where large integers must not lose precision. Avoid it if scripts depend on object key order, on keys_unsorted, or on the --sort-keys (-S) option, since gojq does not implement them. It also omits input_line_number, $__loc__, get_jq_origin, get_prog_origin, and get_search_list by design, and every mathematical function including floor and round converts integers to floating point even though the arithmetic operators do not.

project readme (upstream, from github) — read inline

gojq

CI Status MIT License release pkg.go.dev

Pure Go implementation of jq

This is an implementation of jq command written in Go language. You can also embed gojq as a library to your Go products.

Usage

 $ echo '{"foo": 128}' | gojq '.foo'
128
 $ echo '{"a": {"b": 42}}' | gojq '.a.b'
42
 $ echo '{"id": "sample", "10": {"b": 42}}' | gojq '{(.id): .["10"].b}'
{
  "sample": 42
}
 $ echo '[{"id":1},{"id":2},{"id":3}]' | gojq '.[] | .id'
1
2
3
 $ echo '{"a":1,"b":2}' | gojq '.a += 1 | .b *= 2'
{
  "a": 2,
  "b": 4
}
 $ echo '{"a":1} [2] 3' | gojq '. as {$a} ?// [$a] ?// $a | $a'
1
2
3
 $ echo '{"foo": 4722366482869645213696}' | gojq .foo
4722366482869645213696  # keeps the precision of large numbers
 $ gojq -n 'def fact($n): if $n < 1 then 1 else $n * fact($n - 1) end; fact(50)'
30414093201713378043612608166064768844377641568960512000000000000 # arbitrary-precision integer calculation

Nice error messages.

 $ echo '[1,2,3]' | gojq '.foo & .bar'
gojq: invalid query: .foo & .bar
    .foo & .bar
         ^  unexpected token "&"
 $ echo '{"foo": { bar: [] } }' | gojq '.'
gojq: invalid json: <stdin>
    {"foo": { bar: [] } }
              ^  invalid character 'b' looking for beginning of object key string

Installation

Homebrew

brew install gojq

mise

mise use -g gojq@latest

Zero Install

0install add gojq https://apps.0install.net/utils/gojq.xml

Build from source

go install github.com/itchyny/gojq/cmd/gojq@latest

Docker

docker run -i --rm itchyny/gojq
docker run -i --rm ghcr.io/itchyny/gojq

Difference to jq

  • gojq is purely implemented with Go language and is completely portable. jq depends on the C standard library so the availability of math functions depends on the library. jq also depends on the regular expression library and it makes build scripts complex.
  • gojq does not keep the order of object keys. I understand this might cause problems for some scripts but basically, we should not rely on the order of object keys. Due to this limitation, gojq does not have keys_unsorted function and --sort-keys (-S) option. I would implement when ordered map is implemented in the standard library of Go but I'm less motivated.
  • gojq supports arbitrary-precision integer calculation while jq does not; jq loses the precision of large integers when calculation is involved. Note that even with gojq, all mathematical functions, including floor and round, convert integers to floating-point numbers; only addition, subtraction, multiplication, modulo, and division operators (when divisible) keep the integer precision. To calculate floor division of integers without losing the precision, use def idivide($n): (. - . % $n) / $n;. To round down floating-point numbers to integers, use def ifloor: floor | tostring | tonumber;, but note that this function does not work with large floating-point numbers and also loses the precision of large integers.
  • gojq behaves differently than jq in some features, expecting jq to fix its behavior in the future. gojq supports string indexing; "abcde"[2] (jq#1520). gojq fixes handling files with no newline characters at the end (jq#2374). gojq fixes @base64d to allow binary string as the decoded string (jq#1931). gojq improves time formatting and parsing; deals with %f in strftime and strptime (jq#1409), parses timezone offsets with fromdate and fromdateiso8601 (jq#1053), supports timezone name/offset with %Z/%z in strptime (jq#929, jq#2195). gojq supports nanoseconds in date and time functions.
  • gojq does not support some functions intentionally; get_jq_origin, get_prog_origin, get_search_list (unstable, not listed in jq document), input_line_number, $__loc__ (performance issue). gojq does not support some flags; --ascii-output, -a (performance issue), --seq (not used commonly), --sort-keys, -S (sorts by default because map[string]any does not keep the order), --unbuffered (unbuffered by default). gojq does not parse JSON extensions supported by jq; NaN, Infinity, and [000]. gojq does not support some regular expression metacharacters, backreferences, look-around assertions, and some flags (regular expression engine differences). gojq does not support BOM (encoding/json does not support this). gojq disallows using keywords for function names (def true: .; true is a confusing query), and module name prefixes in function declarations (using module prefixes like def m::f: .; is undocumented).
  • gojq supports reading from YAML input (--yaml-input) while jq does not. gojq also supports YAML output (--yaml-output).

Color configuration

The gojq command automatically disables coloring output when the output is not a tty. To force coloring output, specify --color-output (-C) option. When NO_COLOR environment variable is present or --monochrome-output (-M) option is specified, gojq disables coloring output.

Use GOJQ_COLORS environment variable to configure individual colors. The variable is a colon-separated list of ANSI escape sequences of null, false, true, numbers, strings, object keys, arrays, and objects. The default configuration is 90:33:33:36:32:34;1.

Usage as a library

You can use the gojq parser and interpreter from your Go products.

package main

import (
	"fmt"
	"log"

	"github.com/itchyny/gojq"
)

func main() {
	query, err := gojq.Parse(".foo | ..")
	if err != nil {
		log.Fatalln(err)
	}
	input := map[string]any{"foo": []any{1, 2, 3}}
	iter := query.Run(input) // or query.RunWithContext
	for {
		v, ok := iter.Next()
		if !ok {
			break
		}
		if err, ok := v.(error); ok {
			if err, ok := err.(*gojq.HaltError); ok && err.Value() == nil {
				break
			}
			log.Fatalln(err)
		}
		fmt.Printf("%#v\n", v)
	}
}
  • Firstly, use gojq.Parse(string) (*Query, error) to get the query from a string.
    • Use gojq.ParseError to get the error position and token of the parsing error.
  • Secondly, get the result iterator
    • using query.Run or query.RunWithContext
    • or alternatively, compile the query using gojq.Compile and then code.Run or code.RunWithContext. You can reuse the *Code against multiple inputs to avoid compilation of the same query.
    • In either case, you cannot use custom type values as the query input. The type should be []any for an array and map[string]any for a map (just like decoded to an any using the encoding/json package). You can't use []int or map[string]string, for example. If you want to query your custom struct, marshal to JSON, unmarshal to any and use it as the query input.
  • Thirdly, iterate through the results using iter.Next() (any, bool). The iterator can emit an error so make sure to handle it. The method returns true with results, and false when the iterator terminates.
    • The return type is not (any, error) because the iterator may emit multiple errors. The jq and gojq commands stop the iteration on the first error, but the library user can choose to stop the iteration on errors, or to continue until it terminates.
      • In any case, it is recommended to stop the iteration on gojq.HaltError, which is emitted by halt and halt_error functions, although these functions are rarely used. The error implements gojq.ValueError, and if the error value is nil, stop the iteration without handling the error. Technically speaking, we can fix the iterator to terminate on the halting error, but it does not terminate at the moment. The halt function in jq not only stops the iteration, but also terminates the command execution, even if there are still input values. So, gojq leaves it up to the library user how to handle the halting error.
    • Note that the result iterator may emit infinite number of values; repeat(0) and range(infinite). It may stuck with no output value; def f: f; f. Use RunWithContext when you want to limit the execution time.

gojq.Compile allows to configure the following compiler options.

  • gojq.WithModuleLoader allows to load modules. By default, the module feature is disabled. If you want to load modules from the file system, use gojq.NewModuleLoader.
  • gojq.WithEnvironLoader allows to configure the environment variables referenced by env and $ENV. By default, OS environment variables are not accessible due to security reasons. You can use gojq.WithEnvironLoader(os.Environ) if you want.
  • gojq.WithVariables allows to configure the variables which can be used in the query. Pass the values of the variables to code.Run in the same order.
  • gojq.WithFunction allows to add a custom internal function. An internal function can return a single value (which can be an error) each invocation. To add a jq function (which may include a comma operator to emit multiple values, empty function, accept a filter for its argument, or call another built-in function), use LoadInitModules of the module loader.
  • gojq.WithIterFunction allows to add a custom iterator function. An iterator function returns an iterator to emit multiple values. You cannot define both iterator and non-iterator functions of the same name (with possibly different arities). You can use gojq.NewIter to convert values or an error to a gojq.Iter.
  • gojq.WithInputIter allows to use input and inputs functions. By default, these functions are disabled.

Bug Tracker

Report bugs at Issues - itchyny/gojq - GitHub.

Author

itchyny ()

License

This software is released under the MIT License, see LICENSE.

Frequently asked questions

Is gojq free to use?

gojq is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does gojq do?

Pure Go implementation of jq

What is gojq written in?

gojq is primarily written in Go. Its source is publicly available at https://github.com/itchyny/gojq, and it has 3,804 GitHub stars.