Start
Getting started
A query is a sequence of tokens read left to right. Each token narrows what came before it, so a query describes a path through the document.
Keys are always double-quoted, because any string is a valid JSON key â including .valid, the empty string, and a lone quote. That means a query needs single quotes in a shell, so the double quotes survive.
echo '{ "name": "jql" }' | jql '"name"'
Read a file by passing it after the query, or pipe into it:
jql '"name"' package.json cat package.json | jql '"name"'
Wrap the whole query in single quotes. Without them your shell eats the double quotes around each key, and the query will not parse.
Reference
The grammar
Every token, with an example you can paste into a shell. Each output below was produced by running against the input beside it.
Object keys
The key selector is the one you will use most. Write selectors next to each other to walk down the document.
Arrays
Arrays are addressed by index or by range. Both accept several values, in any order you like.
Objects
Objects can be addressed by name, and also by position â useful when you know the shape but not the keys.
Operators
Four operators reshape what a selector returned rather than descending into it.
The keys operator returns keys sorted alphabetically, not in document order, and the truncate operator may appear only once, as the final token of a query.
Pipes
A pipe applies the tokens that follow to every element of an array, then optionally collapses the result back to a single value.
Lenses
A lens filters an array, keeping the elements that match. It is the only token that removes elements rather than selecting them.
Groups
A comma splits a query into sub-queries, each run against the same input, collected into an array.
Putting it together
Real queries chain these pieces, and reading one from left to right tells you the whole pipeline. Every example below runs against this document:
Using it
Many documents
Input may hold more than one JSON document. Each is evaluated on its own and produces its own result.
Anything trailing that is not itself a document is an error rather than being ignored, so a truncated stream fails loudly instead of returning partial results.
Flags
Eight flags, all short. The full list is in jql --help.
| Flag | What it does |
|---|---|
-i, --inline | Print the output on one line instead of pretty-printing it. |
-q, --query <FILE> | Read the query from a file rather than the command line. |
-r, --raw-string | Print a string result without its surrounding quotes. |
-S, --sort-keys | Sort the keys of every object recursively, like jq -S. |
-s, --stream | Process input line by line as it arrives, one document per line. |
-v, --validate | Ignore the query and report whether the input is valid JSON. |
-h, --help | Print help, including the whole grammar. |
-V, --version | Print the version. |
Shell integration
jql eats JSON and writes JSON back, so it composes with everything else in a pipeline.
Save the output
jql '"repos"' input.json > output.json
Assign a value to a variable
Combine --raw-string with --inline so the result arrives without quotes or newlines:
name=$(jql -r -i '"name"' package.json)
Keep the query in a file
Long queries are easier to read, and to version, when they live on disk:
jql --query ./select-repos.jql input.json
Follow a stream
Without --stream the whole input is read before anything is written, which is right for a file or a finished pipe. With it, each line is processed as it arrives â for output still being produced:
docker logs --follow my-container | jql --stream '"message"'
It expects one document per line. A document spread over several lines needs the default mode.
Check exit codes
jql --validate input.json && echo "valid"
Installation
Packaged for most platforms, or grab a prebuilt binary.
| Platform | Command |
|---|---|
| Cargo | cargo install jql |
| Cargo Binstall | cargo binstall jql |
| Alpine Linux | apk add jql |
| Arch Linux | yay -S jql |
| Fedora | dnf install jql |
| FreeBSD | pkg install jql |
| Homebrew | brew install jql |
| Nix | nix-env -i jql |
| openSUSE | zypper install jql |
Prebuilt binaries for Linux, macOS and Windows are attached to every release.
Good to know
Errors say what went wrong
A failed selection reports the token that failed and the value it was applied to, rather than returning null and leaving you to guess.
It is not jq
There is no plan to align jql with jq or any similar tool. jql selects and reshapes; it has no expression language, no arithmetic and no user-defined functions, and that is deliberate.
Speed
Selection queries run against a simd-json tape, so only the part of the document a query actually selects is ever built. Measurements against jq live in PERFORMANCE.md.
Two JSON parsers are in play, and they round the last bit of some scientific-notation literals differently, by up to two ULP. The tape returns the correctly rounded value. Plain decimals, integers and strings are unaffected.