If you've ever needed to pull a specific value out of a deeply nested JSON object, you know the routine: chain a few bracket and dot accesses, handle nulls, test in a REPL. JSONPath offers a cleaner alternative. It is a query language for JSON, analogous to XPath for XML, that lets you extract one or many values using a single expression rather than imperative code.
JSONPath isn't part of the JSON standard, but it is supported in a wide range of tools, libraries, and platforms including Kubernetes, AWS Step Functions, Grafana dashboards, REST client tools, and dozens of languages with a JSONPath library available. The JSON Path Tester on DevToolShack lets you test expressions against any JSON in your browser, with no setup required.
The Basic Syntax
All JSONPath expressions start with $, which represents the root of the document. From there, you navigate the structure using dot notation or bracket notation.
Given this sample JSON:
{
"store": {
"name": "The Book Depot",
"books": [
{ "title": "Clean Code", "author": "Martin", "price": 32.99, "inStock": true },
{ "title": "SICP", "author": "Abelson", "price": 45.00, "inStock": false },
{ "title": "The Pragmatic Programmer", "author": "Hunt", "price": 38.50, "inStock": true }
],
"location": {
"city": "Austin",
"state": "TX"
}
}
}
Dot notation for object keys
$.store.name
// → "The Book Depot"
$.store.location.city
// → "Austin"
Bracket notation for array indexes
$.store.books[0].title
// → "Clean Code"
$.store.books[2].price
// → 38.50
Wildcards
The * wildcard matches all elements at a level.
$.store.books[*].title
// → ["Clean Code", "SICP", "The Pragmatic Programmer"]
$.store.*
// → all values in the store object
Recursive descent
The .. operator searches the entire document recursively for a key, regardless of nesting depth. This is useful when you don't know exactly where a value lives in the structure.
$..title
// → ["Clean Code", "SICP", "The Pragmatic Programmer"]
$..price
// → [32.99, 45.00, 38.50]
Array slicing
JSONPath borrows Python-style array slice syntax: [start:end:step]. Omitted values use sensible defaults (0 for start, length for end, 1 for step).
$.store.books[0:2].title
// → ["Clean Code", "SICP"] (index 0 and 1, not including 2)
$.store.books[-1].title
// → "The Pragmatic Programmer" (last element)
$.store.books[::2].title
// → ["Clean Code", "The Pragmatic Programmer"] (every other element)
Filter Expressions
Filter expressions are where JSONPath becomes genuinely powerful. The syntax is [?(...)], with @ representing the current element being tested.
Filter by value comparison
$.store.books[?(@.price < 40)].title
// → ["Clean Code", "The Pragmatic Programmer"]
$.store.books[?(@.inStock == true)].title
// → ["Clean Code", "The Pragmatic Programmer"]
Filter by key existence
$.store.books[?(@.author)].title
// → all books that have an "author" key
Filter by string match
Support for string operations in filters varies by implementation. Some support =~ for regex matching; others use functions like @.title =~ /Code/. Check the documentation for whichever library or tool you're using.
JSONPath in Real-World Tools
JSONPath expressions show up in more places than most developers expect.
Kubernetes uses JSONPath in kubectl output formatting. kubectl get pods -o jsonpath='{.items[*].metadata.name}' extracts the name of every pod from the response without parsing JSON manually.
AWS Step Functions uses JSONPath for input/output path processing, letting you extract specific parts of a Lambda function's output to pass to the next state.
Grafana uses JSONPath in its JSON data source plugin to map fields from an API response to chart series and labels.
REST clients like Insomnia and Postman support JSONPath in test scripts and response assertions, letting you write jsonPath(response.body, '$.user.id') to validate specific values in API responses.
Java's Jackson library and Python's jsonpath-ng both support JSONPath expressions natively, as do PHP, Go, and most other major language ecosystems.
jq is more powerful than JSONPath and is the de facto standard for terminal JSON processing. But JSONPath has much wider support in libraries and platforms where you can't run a subprocess. They solve overlapping but distinct problems.Implementation Differences to Watch For
JSONPath does not have a single authoritative standard, though RFC 9535 (published in 2024) is the most complete specification to date. Different libraries implement different subsets of the syntax, so a few things are worth checking when switching between implementations:
- Filter function support. Some implementations support
length(),keys(), andmatch()inside filters; others don't. - Return type. Some implementations always return an array; others return a scalar when only one value matches. This affects how you consume the result in code.
- Recursive descent behavior. The
..operator can behave differently when it encounters arrays versus objects in different libraries. - Negative array indexes.
[-1]for the last element is widely supported but not universal.
Testing your expressions in a live environment before embedding them in production code is always a good idea. The JSON Path Tester lets you paste in your actual JSON and iterate on your expression until it returns exactly what you expect.
Using the JSON Path Tester
The JSON Path Tester on DevToolShack takes two inputs: a JSON document and a JSONPath expression. It runs the expression against the document and shows you the matched result, making it straightforward to develop and debug expressions before using them in code or configuration.
It pairs well with the JSON Formatter, which lets you validate and pretty-print JSON before testing paths against it. If you need to convert JSON to a different format for a downstream system, the JSON to CSV and JSON to XML tools handle that without any code.
For a broader look at working with JSON data, see How to Format and Validate JSON Online and How to Convert JSON to CSV (and Back).