Almost every API and config file today returns JSON, and reading it raw in a terminal is a mess. jq is the tool that fixes that: a command-line JSON processor written by Stephen Dolan, now maintained by an open source team. It filters, transforms, and pretty-prints JSON. After a five-year gap between releases, jq 1.6 (November 2018) was followed by jq 1.7 in September 2023, and it remains a fixture in any developer's toolkit because there is nothing simpler for turning API output into something you can actually read.
Install and pretty-print
Check you have it:
jq --version
On Debian and Ubuntu it is one install away:
sudo apt install jq
It is also in Homebrew on macOS and packaged for most distros. jq reads JSON on standard input and pretty-prints by default, so piping into it instantly beats staring at a minified blob:
echo '{"name":"devlog","tags":["blog","tech"]}' | jq .
The . means "the whole input". Its output is the formatted version, with keys sorted on some versions and always readable.
Reading values and walking paths
jq expressions are small programs. Pull a field with .name:
echo '{"name":"devlog","tags":["blog","tech"]}' | jq .name
Walk nested objects with dots, and index arrays with brackets:
jq '.user.name'
jq '.items[0]'
The . in jq is an identifier /name/ operator, not a string in quotes. So jq .name and jq '.name' are the same, and quoting the whole expression protects it from the shell.
Arrays and filtering
.list[] iterates over every element of the array list, running your filter once per element:
echo '{"items":["a","b","c"]}' | jq '.items[]'
# "a"
# "b"
# "c"
select keeps items that match a condition:
echo '[{"id":1,"active":true},{"id":2,"active":false}]' \
| jq '.[] | select(.active)'
This iterates the outer array with .[], pipes each object into select(.active), and keeps the ones where active is true.
Transforming output
You can reshape as you go. Pick two fields out of an array of objects into new objects:
echo '[{"name":"a","cpu":5},{"name":"b","cpu":9}]' \
| jq 'map({name, cpu})'
map applies a filter to every element and collects the results. To count items, length is built in:
echo '[1,2,3]' | jq 'length' # 3
Realistic usage
Fetch an API and pull out just the fields you want, no browser and no copy-paste. Combined with curl:
curl -s https://api.example.com/users \
| jq '.[] | select(.role == "admin") | {name, email}'
(api.example.com is a placeholder, swap in any endpoint that requires no auth.)
When it is enough
jq is one small executable with no dependencies and no config file, and its filters cover the vast majority of "turn this API response into what I need" jobs. It is not a full programming language, and for complicated transforms you may outgrow it. But for inspecting JSON, extracting fields, filtering arrays, and building clean output for logs and scripts, jq is the fastest answer, and its syntax carries over to tools that reuse the same filter language.