Est. 2012 Intermediate

jq

A lightweight, purely functional command-line language for slicing, filtering, and transforming JSON — often described as "sed and awk for JSON data."

Created by Stephen Dolan

Paradigm Functional, domain-specific: stream-oriented, purely functional transformation of JSON values through composable filters and pipelines, written in a largely tacit (point-free) style
Typing Dynamically typed; every value is one of the JSON types — null, boolean, number, string, array, or object
First Appeared 2012
Latest Version 1.8.1 (1 July 2025)

jq is a small but surprisingly powerful command-line tool — and a complete domain-specific programming language — for working with JSON. You hand it a stream of JSON and a filter, and it produces a transformed stream of JSON. Its own documentation describes it as being “like sed for JSON data”: you can slice, filter, map, and reshape structured data with the same kind of terse, composable expressions that make sed and awk indispensable for plain text. First released by Stephen Dolan in 2012, jq has become a near-universal fixture of shell scripts, CI/CD pipelines, and cloud tooling — the tool reached for the moment a command spits out JSON that needs to be queried or reshaped.

History & Origins

jq was created by Stephen Dolan and first appeared in 2012. The motivation was a familiar one: the Unix command line had decades of excellent text-processing tools — grep, sed, awk, cut — but they all treat input as flat streams of lines and characters. As JSON became the lingua franca of web APIs and configuration, piping that JSON through line-oriented tools was awkward and error-prone. jq filled the gap by treating JSON values as its native unit of work rather than lines of text.

A frequently repeated detail of jq’s history is that the language was first prototyped in Haskell before being rewritten in portable C with no runtime dependencies. That choice paid off: a single, dependency-free C binary is trivial to install everywhere, which is a large part of why jq spread so quickly into scripts, container images, and CI environments.

For its first several years jq was effectively a one-maintainer project, and after the 1.6 release in 2018 it went quiet for nearly five years. In 2023 the project was revived: it moved to a dedicated jqlang GitHub organization, the original repository was transferred from Stephen Dolan, and an expanded team of maintainers shipped the long-awaited 1.7 release. Development has continued steadily since, through the 1.8 series in 2025.

Design Philosophy

jq is built around a single, elegant idea: everything is a filter, and filters compose with a pipe.

  • Filters, not statements. A jq program is a filter — a function from an input value to a (possibly empty, possibly multiple-valued) stream of output values. The identity filter . simply emits its input unchanged.
  • Composition with |. Just like the Unix shell pipe, jq’s | feeds the output of one filter into the next. .users | .[] | .name walks into the users field, iterates the array, and pulls out each name.
  • Streams of values. Filters don’t return a single result; they produce a stream. A filter like .[] emits each element of an array in turn, and downstream filters run once per value. This stream model is what makes jq concise — much of the iteration is implicit.
  • Purely functional. jq has no mutable variables in the imperative sense and no side effects on its data. You describe transformations declaratively, and jq applies them.
  • Tacit, point-free style. Because the input is always the implicit ., many jq programs never name their data at all, reading almost like a path expression.

This design makes simple things very short — jq '.name' extracts a field — while still scaling up to genuinely complex transformations.

Key Features

Filters and pipelines

The core of jq is field access, array iteration, and piping:

1
2
3
4
5
# Extract the name of every user
echo '{"users":[{"name":"Ada"},{"name":"Linus"}]}' \
  | jq '.users[].name'
# "Ada"
# "Linus"

Constructing new JSON

jq can build new objects and arrays, not just extract values:

1
2
# Reshape each user into a new object
jq '.users | map({user: .name, active: true})'

Built-in functions and the standard library

jq ships with a rich set of builtins — map, select, group_by, sort_by, unique, min, max, add, length, keys, to_entries, from_entries, and many more — that cover most data-wrangling needs:

1
2
# Keep only active users, then list their names sorted
jq '[.users[] | select(.active)] | sort_by(.name) | map(.name)'

Variables, reductions, and control flow

While jq leans functional, it provides as bindings, if/then/elif/else/end, reduce, and foreach for accumulation and conditional logic:

1
2
# Sum a list of numbers with reduce
jq 'reduce .[] as $n (0; . + $n)'

Regular expressions and modules

Since jq 1.5, the language has included regular-expression support (via the Oniguruma engine) through functions like test, match, capture, sub, and gsub, along with a module system for sharing reusable definitions.

Turing completeness

Although it is a domain-specific language, jq is Turing-complete — a fact demonstrated playfully by community projects such as Brainfuck interpreters written entirely in jq. In practice this means jq can express recursion and arbitrary computation, even though its sweet spot remains data transformation.

Evolution

VersionApprox. dateHighlights
1.5August 2015Regular expressions (Oniguruma), module system, SQL-style operators, many new builtins
1.6November 2018Performance work, number/decimal fixes, additional builtins
1.7September 2023First release in ~5 years; project moved to the jqlang organization with new maintainers
1.7.1December 2023Patch release fixing regressions in 1.7
1.8.01 June 2025New features and builtins; later partially revised in 1.8.1
1.8.11 July 2025Security and build fixes, including CVE-2025-49014; reverted a 1.8.0 performance regression

jq’s influence is also visible in its reimplementations. gojq, written in Go by itchyny (with first public versions appearing around 2019), reimplements much of the language and adds conveniences like YAML support, and it has been embedded in other tools. jaq, a Rust implementation by Michael Färber, was developed alongside a formal, denotational semantics for the language and focuses on correctness and speed. The existence of multiple independent implementations is a sign that jq’s expression language has become a small standard in its own right.

Current Relevance

jq is, today, one of the most widely deployed command-line tools that most users never think of as a “programming language.” It is pre-installed on common CI runners, recommended in major cloud vendors’ CLI documentation, packaged in virtually every Linux distribution and Homebrew, and bundled into countless container images. Whenever a tool emits JSON and a human needs to pick it apart in a shell, jq is the default answer.

The 2023 revival under the jqlang organization put the project back on a healthy footing after years of stagnation, and the 1.7 and 1.8 release lines show active, security-conscious maintenance. Meanwhile, alternative implementations like gojq and jaq keep the language ecosystem competitive and push performance and correctness forward.

Why It Matters

jq matters because it brought the Unix pipeline philosophy into the age of structured data. The classic text tools — grep, sed, awk — assume the world is made of lines; jq assumes the world is made of JSON values, and it preserves the same composable, do-one-thing-well spirit. In doing so it made JSON a first-class citizen of the command line and demonstrated that a tightly scoped, purely functional domain-specific language can become genuinely indispensable infrastructure. For a tool that fits in a single dependency-free binary, jq has had an outsized impact on how developers and operators interact with the JSON that now underpins nearly every API and configuration system.

Timeline

2012
Stephen Dolan releases the first version of jq, a small command-line JSON processor written in portable C, pitched as a 'sed for JSON data' that filters and transforms JSON with a concise, composable syntax
2015
jq 1.5 is released (around 15 August 2015), adding regular-expression support via the Oniguruma library, a module system, SQL-style set operators, and many new builtins — a substantial expansion of the language
2018
jq 1.6 is released (around November 2018), bringing performance improvements, decimal-number handling fixes, and additional builtins; it then remained the stable release for nearly five years
2019
itchyny releases gojq, a pure-Go reimplementation of jq that adds features such as YAML support and is later embedded in other tools, demonstrating jq's reach beyond its original C implementation (first public versions appeared around 2019)
2023
After a long period of inactivity, the project moves to a new 'jqlang' GitHub organization with an expanded maintainer team, and jq 1.7 ships in September 2023 — the first release in nearly five years — followed by the 1.7.1 patch release in December 2023
2025
jq 1.8.0 is released on 1 June 2025, followed quickly by the 1.8.1 patch release on 1 July 2025, which addresses security issues (including CVE-2025-49014) and a performance regression introduced in 1.8.0

Notable Uses & Legacy

AWS CLI and cloud tooling

Amazon's AWS CLI documentation recommends jq for filtering and reshaping the JSON that cloud CLIs return, letting operators extract instance IDs, ARNs, and nested attributes directly in shell pipelines.

CI/CD pipelines

jq is pre-installed on GitHub-hosted Actions runners and is widely used in GitHub Actions, GitLab CI, and similar systems to parse API responses, read workflow outputs, and build dynamic job matrices from JSON.

Kubernetes operations

Operators routinely pipe 'kubectl get ... -o json' into jq to query pod status, container images, labels, and resource fields when kubectl's built-in JSONPath output is too limited for the task.

yq and JSON/YAML tooling

Andrey Kislyuk's 'yq' wraps jq directly to apply jq filters to YAML, XML, and TOML, while Mike Farah's Go-based 'yq' draws on the same expression style — extending jq's query model across configuration formats.

Shell scripting and API exploration

Developers pair jq with curl, HTTPie, and shell scripts to inspect and transform REST and GraphQL responses interactively, making it a default tool for ad-hoc JSON wrangling at the terminal.

Language Influence

Influenced By

Influenced

gojq jaq

Running Today

Run examples using the official Docker image:

docker pull
Last updated: