Home → JSONPath Cheatsheet

JSONPath Cheatsheet: Complete Syntax Reference with Examples (2026)

📅 Updated March 2026 ⏱ 10 min read 🔍 For backend & data developers
SG
By Saurabh Goyal · Independent Software Developer
Builds JSON Web Tools · GitHub · About the author

JSONPath is the standard way to query and extract data from JSON documents. Think of it as SQL for JSON, or XPath for JSON. This cheatsheet covers every operator, expression, and pattern you'll encounter — with real examples for each.

Test JSONPath expressions live

Enter your JSON and run any expression from this cheatsheet instantly.

Quick Reference: All JSONPath Operators

Root & Navigation

SymbolMeaning
$Root element
.Child element
..Recursive descent
*Wildcard (all)
@Current element

Array Operators

ExpressionMeaning
[0]First element
[-1]Last element
[0,2]Elements 0 and 2
[0:3]Slice: elements 0–2
[::2]Every 2nd element

Filter Expressions

ExpressionMeaning
[?(@.age)]Has age property
[?(@.age > 18)]age greater than 18
[?(@.name == "x")]name equals "x"
[?(@.tags =~ /js/)]Regex match
[?(!@.disabled)]Negation filter

Comparison Operators

OperatorMeaning
==Equal to
!=Not equal
<Less than
>Greater than
<=Less or equal
>=Greater or equal
&&Logical AND
||Logical OR

Sample JSON for All Examples

All examples below use this JSON document:

{
  "store": {
    "name": "The Book Shop",
    "books": [
      { "title": "Clean Code", "author": "Robert Martin", "price": 29.99, "category": "programming", "tags": ["code", "best-practices"] },
      { "title": "The Pragmatic Programmer", "author": "David Thomas", "price": 35.00, "category": "programming" },
      { "title": "Design Patterns", "author": "GoF", "price": 49.99, "category": "architecture" },
      { "title": "JavaScript: The Good Parts", "author": "Douglas Crockford", "price": 19.99, "category": "javascript" }
    ],
    "manager": { "name": "Jane Doe", "email": "jane@bookshop.com" }
  },
  "currency": "USD"
}

Basic Path Navigation

Access a direct child

$.currency
// Result: "USD"

$.store.name
// Result: "The Book Shop"

$.store.manager.email
// Result: "jane@bookshop.com"

Access array elements by index

$.store.books[0]
// Result: { "title": "Clean Code", "author": "Robert Martin", ... }

$.store.books[0].title
// Result: "Clean Code"

$.store.books[-1].title
// Result: "JavaScript: The Good Parts"  (last element)

Wildcards

The * wildcard matches all children of an element:

$.store.books[*].title
// Result: ["Clean Code", "The Pragmatic Programmer", "Design Patterns", "JavaScript: The Good Parts"]

$.store.books[*].price
// Result: [29.99, 35.00, 49.99, 19.99]

$.store.*
// Result: all values inside store (books array, manager object)

Recursive Descent (..)

The .. operator searches recursively at any depth:

$..title
// Result: all title properties anywhere in the document
// ["Clean Code", "The Pragmatic Programmer", "Design Patterns", "JavaScript: The Good Parts"]

$..name
// Result: ["The Book Shop", "Jane Doe"]  — finds name at any level

$..price
// Result: [29.99, 35.00, 49.99, 19.99]

Use recursive descent sparingly. On large documents, .. is slower than a direct path since it must scan the entire tree.

Array Slicing

Array slices work like Python slices — [start:end:step]:

$.store.books[0:2]
// Result: first 2 books (index 0 and 1)

$.store.books[1:]
// Result: all books from index 1 onwards

$.store.books[:2]
// Result: first 2 books (same as [0:2])

$.store.books[::2]
// Result: every 2nd book (index 0, 2)

$.store.books[-2:]
// Result: last 2 books

Multiple Indexes (Union)

$.store.books[0,3].title
// Result: ["Clean Code", "JavaScript: The Good Parts"]

$.store.books[0]['title','author']
// Result: { "title": "Clean Code", "author": "Robert Martin" }

Filter Expressions

Filter expressions use ?(@.field operator value) syntax. @ refers to the current array item:

Filter by existence

$.store.books[?(@.tags)]
// Result: books that HAVE a tags property
// [{ "title": "Clean Code", ..., "tags": ["code", "best-practices"] }]

Filter by comparison

$.store.books[?(@.price < 30)].title
// Result: ["Clean Code", "JavaScript: The Good Parts"]

$.store.books[?(@.price >= 35)].title
// Result: ["The Pragmatic Programmer", "Design Patterns"]

$.store.books[?(@.price == 19.99)].title
// Result: ["JavaScript: The Good Parts"]

Filter by string equality

$.store.books[?(@.category == "programming")].title
// Result: ["Clean Code", "The Pragmatic Programmer"]

$.store.books[?(@.author != "GoF")].title
// Result: ["Clean Code", "The Pragmatic Programmer", "JavaScript: The Good Parts"]

Multiple conditions (AND / OR)

$.store.books[?(@.price < 40 && @.category == "programming")].title
// Result: ["Clean Code", "The Pragmatic Programmer"]

$.store.books[?(@.price > 45 || @.category == "javascript")].title
// Result: ["Design Patterns", "JavaScript: The Good Parts"]

Bracket Notation vs Dot Notation

JSONPath supports both dot and bracket notation. They are equivalent:

Dot NotationBracket NotationNotes
$.store.name$['store']['name']Standard access
$.store.books[0]$['store']['books'][0]Array index
N/A$['my-key']Keys with hyphens need brackets
N/A$['key with spaces']Keys with spaces need brackets

Complete Reference Table

ExpressionDescriptionExample Result
$Root objectEntire document
$.storeDirect childThe store object
$.store.*All children of storebooks array, manager, name
$..titleAll titles anywhereArray of all title values
$.store.books[0]First bookClean Code object
$.store.books[-1]Last bookJS Good Parts object
$.store.books[*].priceAll prices[29.99, 35, 49.99, 19.99]
$.store.books[0:2]First 2 booksArray of 2 books
$.store.books[?(@.price<30)]Books under $30Clean Code, JS Good Parts
$.store.books[?(@.tags)]Books with tagsClean Code only
$.store.books[0,2]Book at index 0 and 2Two specific books

JSONPath in Different Languages

JSONPath is implemented in every major language. Below are copy-paste snippets for JavaScript/Node.js, Python (jsonpath-ng), Java, Go, PHP, C#, and Kotlin — the runtimes developers ask about most. Each uses the same query, $.store.books[*].title, against the sample JSON above so you can compare libraries side by side.

JavaScript / Node.js

// Using jsonpath-plus (npm install jsonpath-plus)
import { JSONPath } from 'jsonpath-plus';

const titles = JSONPath({ path: '$.store.books[*].title', json: data });
// Result: ["Clean Code", "The Pragmatic Programmer", ...]

Python (jsonpath-ng)

jsonpath-ng (imported as jsonpath_ng) is the most widely used JSONPath library for Python. Install it with pip install jsonpath-ng, then parse() your expression once and call .find() to evaluate it against any data:

# Using jsonpath-ng (pip install jsonpath-ng)
from jsonpath_ng import parse

expr = parse('$.store.books[*].title')
matches = [match.value for match in expr.find(data)]
# Result: ["Clean Code", "The Pragmatic Programmer", ...]

# jsonpath-ng also supports the extended filter syntax via jsonpath_ng.ext:
from jsonpath_ng.ext import parse as parse_ext
cheap = parse_ext('$.store.books[?(@.price < 10)].title').find(data)

Note: the base jsonpath_ng.parse covers standard selectors; for filter expressions like ?(@.price<10) use jsonpath_ng.ext. Reusing a parsed expr across calls is faster than re-parsing the string each time.

Java (Spring / Jayway)

// Using Jayway JSONPath (Maven: com.jayway.jsonpath:json-path)
import com.jayway.jsonpath.JsonPath;

List<String> titles = JsonPath.read(json, "$.store.books[*].title");
// Result: ["Clean Code", "The Pragmatic Programmer", ...]

Go

// Using github.com/PaesslerAG/jsonpath
import "github.com/PaesslerAG/jsonpath"

result, _ := jsonpath.Get("$.store.books[*].title", data)

PHP

The standard JSONPath library for PHP is galbar/jsonpath (or the older flow/jsonpath). Install with Composer — composer require galbar/jsonpath — then evaluate expressions against a decoded array:

<?php
// composer require galbar/jsonpath
use JSONPath\JSONPath;

$data = json_decode($json, true);
$titles = (new JSONPath($data))->find('$.store.books[*].title')->getData();
// Result: ["Clean Code", "The Pragmatic Programmer", ...]

// Filter expressions work the same way in PHP:
$cheap = (new JSONPath($data))->find('$.store.books[?(@.price < 10)].title');
?>

C# / .NET

In C#, JSONPath is built into Newtonsoft.Json (Json.NET) via SelectTokens — no extra package beyond Json.NET. System.Text.Json does not support JSONPath natively, so Json.NET remains the standard choice:

// using Newtonsoft.Json.Linq;
JObject root = JObject.Parse(json);

// SelectTokens returns every match for a JSONPath query
var titles = root.SelectTokens("$.store.books[*].title")
                 .Select(t => t.ToString());
// Result: ["Clean Code", "The Pragmatic Programmer", ...]

// SelectToken (singular) returns the first match, or null:
string first = (string)root.SelectToken("$.store.books[0].title");

Kotlin

On the JVM, Kotlin uses the same Jayway JSONPath library as Java. Add com.jayway.jsonpath:json-path to your Gradle dependencies, then read paths directly:

// implementation("com.jayway.jsonpath:json-path:2.9.0")
import com.jayway.jsonpath.JsonPath

val titles: List<String> = JsonPath.read(json, "$.store.books[*].title")
// Result: ["Clean Code", "The Pragmatic Programmer", ...]

// Filter expressions work the same way in Kotlin:
val cheap: List<String> = JsonPath.read(json, "$.store.books[?(@.price < 10)].title")

String Matching in Filters: contains, substring & regex

Beyond == and </> comparisons, most JSONPath engines support string functions inside filter expressions. Support varies by library, so test against your runtime:

GoalExpressionNotes
Substring / contains$.store.books[?(@.title =~ /.*Code.*/)]Regex match (Jayway, jsonpath-ng.ext). Matches any title containing "Code".
Starts with$..[?(@.name =~ /^Sci.*/i)]The i flag makes it case-insensitive.
Substring via function$.store.books[?(@.title contains 'Code')]Some engines (e.g. Goessner-style ports) expose a contains keyword instead of regex.
Length$.store.books[?(@.title.length() > 10)]Jayway supports inline functions like length().

There is no single standard for string functions in JSONPath, so =~ regex (the most widely implemented) is the safest way to do "contains", "substring", and "matches" queries. The live evaluator uses regex-style matching so you can confirm an expression before shipping it.

Newlines & Escaping in JSONPath

Two common gotchas when a path or value contains special characters:

JSONPath Alternatives

JSONPath is the most common query language for JSON, but it is not the only one. If JSONPath does not fit your use case, these are the main alternatives developers reach for:

ToolBest forExample
JMESPathA formal spec with built-in functions, multiselect, and pipes. Used by the AWS CLI. More predictable than JSONPath across implementations.store.books[*].title
jqCommand-line JSON processing and transformation in shell scripts. Far more powerful than JSONPath but a different syntax..store.books[].title
JSON Pointer (RFC 6901)Addressing a single, exact location in a document (no wildcards or filters). Used by JSON Patch and OpenAPI $ref./store/books/0/title
GraphQLQuerying an API where the server shapes the response. Not for querying static documents.{ store { books { title } } }

Rule of thumb: use JSONPath for ad-hoc extraction with wildcards and filters, JMESPath when you need a stable cross-language spec, jq for shell pipelines, and JSON Pointer when you only need one exact path. You can prototype any JSONPath expression in the live JSONPath evaluator before porting it to your language of choice.

Common JSONPath Patterns

These are the patterns developers use most often:

TaskJSONPath
Get all IDs$..id
Get first item in every array$..[0]
Find active users$.users[?(@.active == true)]
Users over 18$.users[?(@.age >= 18)]
Items with price in range$.items[?(@.price >= 10 && @.price <= 50)]
All leaf node values$..*
Count items (length)$.items.length
Non-null field$.users[?(@.email != null)]

JSONPath vs XPath Comparison

FeatureJSONPathXPath
Root$/
Child./
Recursive..//
Wildcard**
Current node@.
Filter[?(@.x > 1)][@x>1]
Array index[0][1] (1-based)
Parent axisNot supported..

Key difference: JSONPath array indexes are 0-based (like JavaScript), while XPath is 1-based.

Test any JSONPath expression live

Paste your JSON and run expressions from this cheatsheet instantly — no install needed.

Frequently Asked Questions

What is JSONPath? +
JSONPath is a query language for JSON, similar to XPath for XML. It lets you select and extract specific elements from a JSON document using path expressions. For example, $.store.books[0].title selects the title of the first book in the store.
What does $ mean in JSONPath? +
$ represents the root element of the JSON document. Every JSONPath expression must start with $. Think of it as the entry point to the entire document — equivalent to / in XPath.
How do I filter an array with JSONPath? +
Use a filter expression: $.books[?(@.price < 20)] returns all books with price less than 20. The @ symbol refers to the current array element being evaluated. You can combine conditions with && (AND) and || (OR).
What is the difference between . and .. in JSONPath? +
A single dot (.) is a child accessor — $.user.name gets the direct name child of user. A double dot (..) is the recursive descent operator — $..name finds all name properties at any depth in the entire document.
Is JSONPath standardized? +
JSONPath was originally defined by Stefan Goessner in 2007 and has been widely adopted but not formally standardized until recently. RFC 9535 (published in 2024) is now the official IETF standard for JSONPath. Different implementations may have minor syntax variations, especially for filters and regex.
How do I get the last element in a JSONPath array? +
Use a negative index: $.books[-1] returns the last element. $.books[-2:] returns the last two elements. This works the same as Python slice notation.

JSONPath Tutorial: Complete Reference

JSONPath is the standard way to extract data from JSON in APIs, automation scripts, and data pipelines. This tutorial covers everything from basic selectors to advanced filter expressions.

Lesson 1: Basic Selectors

// JSON
{"user": {"name": "Alice", "age": 30, "city": "London"}}

// Basic selectors
$              → entire document
$.user         → {"name":"Alice","age":30,"city":"London"}
$.user.name    → "Alice"
$.user.age     → 30

Lesson 2: Array Navigation

// JSON
{"items": ["apple", "banana", "cherry"]}

// Array selectors
$.items        → ["apple","banana","cherry"]
$.items[0]     → "apple"
$.items[2]     → "cherry"
$.items[-1]    → "cherry" (last)
$.items[0:2]   → ["apple","banana"] (slice)
$.items[*]     → all items

Lesson 3: Recursive Descent

// JSON with nested structure
{"a": {"b": {"id": 1}}, "c": {"id": 2}, "id": 3}

// Recursive descent
$..id  → [1, 2, 3]  // finds "id" at ALL depths
$..b   → [{"id": 1}]

Lesson 4: Filter Expressions

// JSON
{"products": [
  {"name": "A", "price": 10, "inStock": true},
  {"name": "B", "price": 25, "inStock": false},
  {"name": "C", "price": 15, "inStock": true}
]}

// Filter expressions
$.products[?(@.inStock)]            → A and C objects
$.products[?(@.price < 20)]         → A and C objects
$.products[?(@.name == "B")]        → B object
$.products[?(@.price >= 15)].name   → ["B","C"]

JSONPath Cheat Sheet

ExpressionMeaning
$Root
$.keyChild key
$[0]First array element
$[-1]Last array element
$[*]All array elements
$..*All values (recursive)
$..keyKey at any depth
$[n:m]Array slice n to m
[?(@.x > 0)]Filter: x greater than 0
[?(@.x)]Filter: x exists
[?(@.x == 'val')]Filter: x equals 'val'

Related Tools & Guides

JSONPath Online Evaluator  |  JSON Schema Tutorial  |  How to Validate JSON  |  JSON vs XML  |  JSON Formatter  |  Full JSON Cheatsheet

JSONPath Cheat Sheet

Use this quick-reference table to look up any JSONPath expression. All expressions start from the root $ symbol and can be combined — for example, $.store.books[?(@.price<10)].title filters books cheaper than $10 and returns their titles.

Expression Description Example
$Root$
.keyChild$.name
..keyRecursive descent$..id
[n]Array index$.items[0]
[-1]Last element$.items[-1]
[*]All elements$.items[*]
[n,m]Multiple indices$.items[0,2]
[n:m]Slice$.items[1:3]
[?(@.k)]Has key[?(@.active)]
[?(@.k==v)]Equals[?(@.price==9)]
[?(@.k>v)]Greater than[?(@.price>10)]
[?(@.k<v)]Less than[?(@.qty<5)]
[?(@.k=~/re/)]Regex match[?(@.name=~/^A/)]

JSONPath in Different Languages

JSONPath has implementations in every major language. The expression syntax is the same; only the library API differs. All four examples below extract every user's email from an array of user objects.

// JavaScript (jsonpath-plus)
import { JSONPath } from 'jsonpath-plus';
const results = JSONPath({ path: '$.users[*].email', json: data });
# Python (jsonpath-ng)
from jsonpath_ng import parse
matches = [m.value for m in parse('$.users[*].email').find(data)]
// Java (Jayway JsonPath)
List<String> emails = JsonPath.read(json, "$.users[*].email");
// Go (gjson)
result := gjson.Get(json, "users.#.email")