JSON Parser Pro
Back to Blog

JSONPath Cheatsheet: 20 Expressions Every Developer Needs

JSONPath is to JSON what XPath is to XML — a small query language for reaching into deeply-nested data and pulling out exactly what you need. Once you've written more than a few nested for-loops to walk an API response, JSONPath starts to feel like a superpower. This cheatsheet covers the 20 expressions you'll use 95% of the time, with runnable examples you can paste into any JSONPath tester.

The sample JSON we'll use

Every example below runs against this store data:

{
  "store": {
    "books": [
      { "title": "The Pragmatic Programmer", "author": "Hunt", "price": 39.95, "inStock": true, "tags": ["classic", "dev"] },
      { "title": "Clean Code",                "author": "Martin", "price": 29.99, "inStock": true, "tags": ["dev"] },
      { "title": "Design Patterns",           "author": "GoF",    "price": 44.95, "inStock": false, "tags": ["classic"] },
      { "title": "Refactoring",               "author": "Fowler", "price": 34.99, "inStock": true, "tags": ["dev"] }
    ],
    "location": { "city": "San Francisco", "country": "USA" }
  },
  "members": 1240
}

1. The basics — $ and dot notation

$ is the root of your document. Chain keys with dots to drill in.

$                          → the whole document
$.store                    → the store object
$.store.location.city      → "San Francisco"
$.members                  → 1240

2. Array indexing

Use square brackets for arrays. Indexes are zero-based, and negative indexes count from the end.

$.store.books[0]           → first book
$.store.books[-1]          → last book
$.store.books[0].title     → "The Pragmatic Programmer"

3. Wildcards — [*] and .*

Wildcards return every child. This is how you 'unwrap' an array without knowing its length.

$.store.books[*]           → every book (array of 4 objects)
$.store.books[*].title     → ["The Pragmatic Programmer", "Clean Code", ...]
$.store.*                  → every value directly under store

4. Array slicing

Same syntax as Python slicing — [start:end:step], end exclusive.

$.store.books[0:2]         → first two books
$.store.books[1:]          → all but the first
$.store.books[::2]         → every other book (indexes 0, 2)

5. Recursive descent — ..

Two dots mean 'find this key anywhere below here, at any depth.' Extremely useful when you don't know the exact path.

$..title                   → every 'title' key anywhere in the doc
$..price                   → every 'price' key
$.store..city              → 'city' anywhere under store

6. Filter expressions — [?(...)]

The killer feature. Filters keep only the items matching a boolean expression. @ refers to the current item being filtered.

$.store.books[?(@.price < 35)]              → books cheaper than $35
$.store.books[?(@.inStock == true)]         → books in stock
$.store.books[?(@.author == "Fowler")]      → books by Fowler
$.store.books[?(@.price >= 30 && @.price <= 40)]  → mid-priced books

7. Combine filters with wildcards

Filters produce arrays, so you can keep chaining.

$.store.books[?(@.inStock)].title           → titles of in-stock books
$.store.books[?(@.price > 30)].author       → authors of pricier books

8. Check for a key's existence

In many implementations, referencing @.key inside a filter returns falsy when the key is missing.

$..books[?(@.discount)]        → only books that have a 'discount' field

9. String matches and regex (implementation-dependent)

Not every JSONPath library supports these, but jsonpath-plus and Goessner-flavored parsers usually do.

$..books[?(@.title =~ /clean/i)]   → titles containing 'clean' (case-insensitive)
$..books[?(@.tags.indexOf('dev') > -1)]  → tagged 'dev'

10. The union operator — [a, b]

Pick multiple specific children in one query.

$.store.books[0, 2]                → first and third book
$.store.books[*]['title', 'price']  → title and price of every book

Common traps

  • Filters must be wrapped in [?(...)] — the ? and parentheses are required.
  • Recursive descent (..) is powerful but slow on huge documents — prefer explicit paths when you know them.
  • JSONPath is not standardized. Different libraries handle edge cases differently (especially script expressions and regex). Test in the library you'll actually ship with.
  • @ is the current item inside a filter — it's easy to confuse with $ (the root).
  • Slice syntax uses colons (0:2), not commas — commas are the union operator.

Test any of these in seconds

Paste your JSON and try the expressions above in our free JSONPath tester — it runs entirely in your browser, no data leaves your device, and results highlight in real time. Perfect for exploring an unfamiliar API response.

Try it yourself

JSONPath Tester

Handles JSON files up to 20MB smoothly