JSONPath is a query language for JSON, similar to XPath for XML. It lets you extract specific values from deeply nested JSON structures using a compact expression syntax. A JSONPath tester online lets you paste your JSON, write expressions, and instantly see the matched results — without running any code.

Try our JSONPath Tester →

JSONPath Syntax Basics

Every JSONPath expression starts from the root $ and navigates the structure using operators.

Root and Dot Notation

{
  "store": {
    "name": "Tech Books",
    "inventory": [
      { "title": "JavaScript: The Good Parts", "price": 29.99, "inStock": true },
      { "title": "Clean Code", "price": 34.99, "inStock": false },
      { "title": "The Pragmatic Programmer", "price": 39.99, "inStock": true }
    ]
  }
}
ExpressionResult
$.store.name"Tech Books"
$.store.inventory[0].title"JavaScript: The Good Parts"
$.store.inventory[2].price39.99

Bracket Notation

Equivalent to dot notation, but required when keys contain spaces or special characters:

$.store['name']             → "Tech Books"
$.store.inventory[0]        → first book object
$.store.inventory[-1]       → last book object (negative indexing)

Wildcard *

Match all children of an object or all elements of an array:

$.store.inventory[*].title
→ ["JavaScript: The Good Parts", "Clean Code", "The Pragmatic Programmer"]

$.store.*
→ ["Tech Books", [...inventory array...]]

Array Slices

Python-style slice syntax [start:end:step]:

$.store.inventory[0:2]          → first two books
$.store.inventory[::2]          → every other book (indices 0, 2, 4...)
$.store.inventory[-1:]          → last book only

Recursive Descent ..

The double-dot operator searches the entire tree for matching keys, regardless of nesting depth:

{
  "orders": [
    { "id": 1, "customer": { "name": "Alice" } },
    { "id": 2, "customer": { "name": "Bob" } }
  ]
}
$..name
→ ["Alice", "Bob"]

$..id
→ [1, 2]

This is especially useful for navigating deeply nested or inconsistently structured JSON responses from APIs.

Filter Expressions ?()

Filter expressions select elements that match a condition. Use @ to refer to the current element:

$.store.inventory[?(@.inStock == true)].title
→ ["JavaScript: The Good Parts", "The Pragmatic Programmer"]

$.store.inventory[?(@.price < 35)].title
→ ["JavaScript: The Good Parts", "Clean Code"]

$.store.inventory[?(@.price >= 35)]
→ [{ "title": "Clean Code", ...}, { "title": "The Pragmatic Programmer", ...}]

Supported comparison operators: ==, !=, <, <=, >, >=.

Some implementations also support:

  • =~ for regex matching: [?(@.title =~ /Code/i)]
  • in for membership: [?(@.category in ['tech', 'science'])]

Real-World JSONPath Examples

API Response Navigation

REST APIs often return deeply nested data. JSONPath cuts straight to what you need:

{
  "data": {
    "users": [
      { "id": 1, "profile": { "email": "[email protected]", "role": "admin" } },
      { "id": 2, "profile": { "email": "[email protected]", "role": "user" } }
    ]
  },
  "meta": { "total": 2 }
}
$.data.users[*].profile.email
→ ["[email protected]", "[email protected]"]

$.data.users[?(@.profile.role == "admin")].id
→ [1]

$.meta.total
→ 2

Config File Queries

JSON config files are common in Node.js and Python projects:

{
  "database": {
    "host": "localhost",
    "port": 5432,
    "credentials": { "username": "app", "password": "secret" }
  },
  "cache": {
    "host": "redis-host",
    "port": 6379
  }
}
$..host
→ ["localhost", "redis-host"]

$..port
→ [5432, 6379]

$.database.credentials.username
→ "app"

AWS / Cloud API Responses

Cloud APIs return complex JSON. JSONPath helps extract specific fields:

$.Reservations[*].Instances[*].InstanceId
$.Items[?(@.Status == "ACTIVE")].ResourceArn
$..Tags[?(@.Key == "Environment")].Value

JSONPath in Different Languages

JSONPath is not a standard built into JSON itself — it’s implemented separately in each language ecosystem.

JavaScript

// Using jsonpath-plus
import { JSONPath } from 'jsonpath-plus';

const result = JSONPath({ path: '$.store.inventory[*].title', json: data });

Python

from jsonpath_ng import parse

expr = parse('$.store.inventory[*].title')
matches = [match.value for match in expr.find(data)]

Java

// Using Jayway JsonPath
import com.jayway.jsonpath.JsonPath;

List<String> titles = JsonPath.read(json, "$.store.inventory[*].title");

Go

// Using gjson
import "github.com/tidwall/gjson"

result := gjson.Get(json, "store.inventory.#.title")

Command Line (jq)

jq uses its own syntax but serves a similar purpose:

# JSONPath equivalent: $.store.inventory[*].title
echo "$json" | jq '.store.inventory[].title'

# Filter equivalent: $.store.inventory[?(@.inStock == true)]
echo "$json" | jq '.store.inventory[] | select(.inStock == true)'

JSONPath vs jq vs XPath

FeatureJSONPathjqXPath
Input formatJSONJSONXML
Recursive descent....//
Filter expressions?(@.x > 5)select(.x > 5)[@x > 5]
TransformsNoYes (full pipeline)Limited
StandardRFC draftNoneW3C standard
CLI toolNoYesxmllint, xmlstarlet

JSONPath is the right choice when you need a query — extracting values from JSON without transforming them. Use jq when you need to transform or reshape data. Use XPath only for XML.

Common JSONPath Mistakes

Forgetting $ at the start: Every expression must begin with $. store.name is invalid; $.store.name is correct.

Off-by-one with array indices: JSONPath arrays are zero-indexed. [0] is the first element, not [1].

Confusing . and ..: A single dot navigates one level. A double dot .. descends recursively through all levels. Using ..key when you mean .key will still return results but may match unexpected nested keys.

Filter syntax variation: ?() filter syntax varies between implementations. Always test your expressions against your specific library.

Online JSONPath Tester

Testing JSONPath expressions by running code — loading a library, parsing JSON, writing the query — takes time. Our JSONPath Tester runs entirely in the browser:

  • Paste any JSON in the left panel
  • Write a JSONPath expression and see matches instantly
  • Results are highlighted in the original JSON tree
  • No installation, no backend, no API calls

Try the JSONPath Tester →