jaq
A correct, fast jq clone written in Rust, with improved error messages and a more predictable handling of edge cases.
jaq (pronounced like "Jacques") is a reimplementation of
jq in Rust. It aims to be a drop-in
replacement for the most common jq use cases while fixing a number of
correctness issues, producing clearer error messages, and running faster on
large inputs.
If you already know jq, you already know most of jaq — the filter language
is largely compatible. The differences are intentional improvements rather than
oversights.
Features
- jq-compatible — the vast majority of real-world
jqfilters work injaqwithout modification - Correctness improvements — fixes several
jqedge cases aroundlimit,first,last,?//(the try-alternative operator), and arithmetic on special values - Better error messages — type errors and parse failures are reported with more context and precision
- Fast — typically faster than
jqon large inputs thanks to Rust's performance characteristics - Streaming support — can process newline-delimited JSON (ndjson) efficiently
- No external dependencies — a single self-contained binary
Installation
cargo install jaq
Or via your system package manager:
# macOS
brew install jaq
# Arch Linux
pacman -S jaq
# Debian / Ubuntu (Debian 13+)
apt install jaq
# Fedora
dnf install jaq
# Nix
nix-env -iA nixpkgs.jaqUsage
jaq accepts the same command-line flags as jq, so existing scripts and
aliases can be swapped in with no changes:
# Pretty-print a JSON file
jaq . file.json
# Extract a field
jaq '.name' file.json
# Extract a nested field
jaq '.user.email' file.json
# Filter an array
echo '[1,2,3,4,5]' | jaq '[.[] | select(. > 3)]'
# → [4, 5]
# Map over an array
echo '[1,2,3]' | jaq '[.[] * 2]'
# → [2, 4, 6]
# Get the keys of an object
echo '{"a":1,"b":2}' | jaq 'keys'
# → ["a", "b"]
# Compact output (no pretty-printing)
jaq -c '.items[]' file.json
# Raw string output (no JSON quoting)
jaq -r '.name' file.json
# Slurp all inputs into an array
jaq -s '.' *.json
# Read raw text input line by line
jaq -R 'split(",")' data.csvWorking with APIs
# Fetch and explore a JSON API response
curl -s https://api.github.com/repos/01mf02/jaq \
| jaq '{name, stars: .stargazers_count, language}'
# Extract all page URLs from a sitemap-style response
curl -s https://api.example.com/pages \
| jaq '[.pages[].url]'
# Process newline-delimited JSON (ndjson)
cat events.ndjson | jaq -c 'select(.type == "click") | .payload'Differences from jq
jaq intentionally diverges from jq in a handful of areas where jq's
behaviour is surprising or incorrect:
| Behaviour | jq | jaq |
|---|---|---|
limit(0; expr) | May evaluate expr | Never evaluates expr |
nan == nan | false | false (consistent with IEEE 754) |
null arithmetic | Varies | Strict type errors |
?// (try-alternative) | Inconsistent | Well-defined semantics |
| Error messages | Often cryptic | Precise and contextual |
For the overwhelming majority of everyday jq usage — filtering, transforming,
and extracting from JSON — the two tools are interchangeable.