Comparison
JSONPath vs jq: Which JSON Query Tool Should You Use?
Both JSONPath and jq answer the same question — “how do I pull specific values out of a JSON document?” — but they answer it at very different levels of ambition. JSONPath is a small path expression language (think CSS selectors, but for JSON). jq is a full, Turing-complete functional programming language for JSON with pipelines, variables, conditionals, and user-defined functions.
For grabbing a few nodes out of an API response, JSONPath is faster to write and can run inside your programming language via a small library. For anything that requires transformation, aggregation, or shape-changing across arrays, jq is dramatically more powerful — and it's the de-facto shell tool for JSON pipelines.
TL;DR
| JSONPath | jq | |
|---|---|---|
| Type | Path expression language | Turing-complete functional language |
| Learning curve | Minutes | Days for real fluency |
| Extract nodes | Yes | Yes |
| Filter by predicate | Yes ([?(@.age > 18)]) | Yes (select(.age > 18)) |
| Transform / reshape | No | Yes (| {new: .old}) |
| Aggregate (sum, group by) | No | Yes (reduce, group_by) |
| Multiple outputs / streams | No — returns node list | Yes — emits value streams |
| Standard | RFC 9535 (Feb 2024) | de facto (jq 1.7 released 2023) |
| Runs in-language | Yes (small libs everywhere) | Via native binary or WASM port |
| Runs on the CLI | Via wrapper tools | Yes — its home turf |
| Typical use | Extract a few nodes from JSON in code | Shell pipelines, data reshaping, ETL |
The options in depth
JSONPath
A compact selector notation — the CSS selectors of JSON.
JSONPath was introduced by Stefan Gössner in 2007, inspired by XPath. It stayed a de-facto standard for over 15 years until RFC 9535 finally standardized it in February 2024. Expressions look like $.store.book[?(@.price < 10)].title: navigate a path, optionally filter with a predicate, return matched nodes.
What JSONPath does not do is transform or aggregate. You can pluck out matching nodes, but you cannot reshape them into a new document, sum a field across items, or compose expressions with a pipe. When you need those, you climb the ladder to jq.
Good for
- ·Extracting a handful of nodes from a JSON payload in application code
- ·Configuration-driven data extraction (Kubernetes .spec.template.metadata.labels)
- ·Postman / Bruno / Bruno tests where the assertion is 'this path exists / equals X'
- ·GitHub Actions expressions (github.event.pull_request.labels.*.name — same lineage)
Avoid when
- ·You need to reshape the output into a different structure
- ·You need aggregations (sum, average, group_by)
- ·You want to chain multiple queries with intermediate variables
jq
A functional programming language purpose-built for JSON pipelines.
jq is what happens when someone decides “awk, but for JSON.” It has pipes (|), variables, conditionals, list comprehensions, user-defined functions, and a full standard library. A jq program like .items | map(select(.active)) | group_by(.category) | map({category: .[0].category, count: length}) filters, groups, and reshapes in one pipeline — impossible in JSONPath.
The cost of that power is a steeper learning curve. jq's streaming, functional semantics take real practice. But once you can write jq comfortably, it replaces small-to-medium ETL scripts you'd otherwise write in Python.
Good for
- ·Shell pipelines: curl … | jq … | psql …
- ·Reshaping API responses into a different JSON structure
- ·Aggregations: sum a field across an array, group by a key, count occurrences
- ·CI/CD scripts: extract a value from kubectl / terraform output as a shell variable
- ·Data cleaning steps in ETL pipelines before loading into a warehouse
Avoid when
- ·You're inside application code where a small JSONPath library is simpler than shelling out to jq
- ·The team doesn't know jq — a 20-line Python script is often more maintainable
- ·You need to invoke jq millions of times per second (process startup dominates)
Which one should you pick?
→ In application code, need to grab a few nodes?
Use JSONPath. A ~5 KB library gets the job done without a shell dependency.
→ On the command line, wrangling JSON output between tools?
Use jq. It's a Unix citizen — jq lives in a pipeline the way awk does for text.
→ Need to reshape or aggregate?
jq — JSONPath simply cannot do this. The moment you find yourself needing map / group_by / to_entries, jq is the answer.
→ One-off ad-hoc query on the terminal?
jq. It's designed for this. JSONPath tools also work but jq's syntax is more expressive for interactive exploration.
Common pitfalls
- ⚠JSONPath implementations disagree on non-standard edge cases (e.g. .. deep descent semantics, filter script contents). RFC 9535 resolved most of these — check that your library is RFC 9535 compliant if portability matters.
- ⚠jq's streaming model surprises newcomers: a filter can emit zero, one, or many values, and | chains them like a stream. Reading jq output as “a single value per line” is not always accurate.
- ⚠jq's process startup adds tens of milliseconds. Inside a tight shell loop, batch inputs together (jq accepts multiple documents from stdin) instead of invoking jq once per record.
- ⚠JSONPath's filter script syntax [?(...)] historically executed arbitrary JavaScript in some implementations. RFC 9535 defines a safe expression grammar — pre-2024 libraries may not.
- ⚠Neither tool changes the source document. Both return a projection. For in-place edits of JSON files, consider a full library (yq --toml-* / dasel / jj) rather than jq alone.
Frequently Asked Questions
Can I use jq inside a browser?
Yes — jq has been ported to WebAssembly (jq-web), so it runs entirely client-side. Bundle size is significant (~1 MB), so it's more common to run it server-side or as a CLI.
Is JSONPath just a subset of jq?
Roughly — every JSONPath expression can be translated to jq, but not vice versa. Think of JSONPath as XPath and jq as XSLT: same substrate, different ambition.
What about JMESPath?
JMESPath is another JSON query language, roughly in the same “more powerful than JSONPath, less than jq” niche. AWS CLI standardized on JMESPath for --query. If you're already in the AWS ecosystem, JMESPath is worth knowing.
Which one should I learn first?
JSONPath — it's smaller, transferable to XPath thinking, and enough for 70% of extraction tasks. Add jq when you start needing transformation or aggregation.
Are there GUI testers for both?
Yes — see our JSONPath Tester. For jq, the community jq play (jqplay.org) is the standard, along with the built-in jq --help for CLI experiments.