mrkeyoor.com_
Sat 08 Aug 21:56 UTC
npmUtilsupdated 08 Aug 2026

jsonpath

jsonpath is a CommonJS query and mutation utility for JavaScript object graphs. It implements the original Goessner-style JSONPath notation, including child and recursive descent, wildcards, unions, array slices, filters, and script subscripts. Beyond returning matching values, it can return concrete key paths, pair paths with values, read or set the first match, find a parent, transform every match in place, and parse or stringify path expressions.

Verdict

A useful compatibility choice for existing Goessner-style paths, especially when path arrays and mutations matter. Start new cross-language systems with a standards-focused engine, and do not run jsonpath versions older than 1.3.0.

API stability4/5The query, paths, nodes, value, parent, apply, parse, and stringify methods documented today have been the package's recognizable surface for years. Version 1.3.0 tightened unsafe expression and path behavior rather than redesigning those calls. Compatibility risk lives mainly in ambiguous JSONPath dialect expectations and formerly accepted dangerous expressions, which security fixes correctly reject even inside a 1.x line.
Docs4/5The README provides a syntax table, a shared sample document, examples for child, descendant, wildcard, slice, union, filter, and script forms, and a method-by-method reference including return shapes. It also explains why static evaluation and the formal grammar differ from the original implementation. It lacks TypeScript guidance, RFC 9535 comparison, performance boundaries, and a visible security-upgrade section.
Maintenance4/5After no release between April 2021 and February 2026, the project published 1.2.0, 1.2.1, and 1.3.0 in quick succession to address prototype-pollution and expression-evaluation vulnerabilities, with the repository pushed in March 2026. That security response is meaningful, though 106 open issues and pull requests and the long prior gap argue against a perfect maintenance score.
Ecosystem4/5The package receives 3,723,509 weekly downloads and has 1,431 GitHub stars, a substantial installed base for a focused query utility. Separate DefinitelyTyped declarations exist, and the familiar Goessner syntax is widely recognized. The ecosystem is fragmented among incompatible JSONPath dialects, JMESPath, and JSONata, so expressions are not automatically portable just because another tool also says JSONPath.

Use it if

  • You maintain a Node.js codebase that already uses Goessner-style JSONPath expressions and needs a current security-fixed release
  • You need both matched values and concrete key-array paths for diagnostics, editors, or targeted updates
  • You want controlled filter expressions without exposing the full JavaScript runtime to the expression
  • You need built-in mutation helpers such as value and apply in addition to read-only queries
Skip it if

Setup reality

`npm install jsonpath` gives you a CommonJS module with three runtime dependencies: the old Esprima 1.2.5 parser, static-eval 2.1.1, and Underscore 1.13.6. There are no peer dependencies or native builds. Version 1.3.0 publishes a browser field, but it does not expose an ESM entry or bundled TypeScript declarations; add `@types/jsonpath` if your compiler needs types and verify that its declarations cover the newest security behavior. The main compatibility decision is syntax. This package follows the original Goessner family rather than promising RFC 9535 conformance, and its formal grammar is intentionally stricter in places. Non-ASCII or punctuation-heavy property names must use quoted bracket notation. Filter and script expressions are parsed and statically evaluated with only `@` in scope; ordinary comparisons and boolean logic work, while method calls, global access, assignments, constructors, and other executable constructs are rejected. That is safer than eval, but it also breaks expressions copied from permissive engines. Pin at least 1.3.0: the 2026 releases added unsafe-key blocks for `__proto__`, `prototype`, and `constructor`, then tightened expression evaluation for CVE-2026-1615. Read methods return arrays, even for one expected result, except `value`, `parent`, and mutations with their own first-match behavior. The optional count argument caps results and can prevent unnecessary traversal. Mutation is easy to overlook: `value(obj, path, newValue)` changes the first match and can create a missing simple path, while `apply` replaces every match in the original object. Clone first if immutable inputs matter, and never accept unrestricted expressions merely because static evaluation is narrower than JavaScript.

Patterns

Return all matching valuesquery-values

const jp = require('jsonpath');

const authors = jp.query(data, '$.store.book[*].author');

query always returns an array. No matches produce an empty array rather than undefined.

Find a property at any depthrecursive-descent

const prices = jp.query(data, '$..price');

Recursive descent scans the nested graph and can return prices from unrelated branches. Prefer a narrower path when structure is known.

Filter objects with comparisons and boolean logicfilter-array

const books = jp.query(
  data,
  '$.store.book[?(@.price < 30 && @.category == "fiction")]'
);

Filters use a restricted static evaluator with only @ in scope. Function calls and access to process or other globals are rejected.

Stop after a fixed number of matcheslimit-results

const firstTwoAuthors = jp.query(data, '$..author', 2);
const none = jp.query(data, '$..author', 0);

The third argument limits returned matches; zero returns an empty array without traversing.

Select a range or the last itemslice-array

const firstTwo = jp.query(data, '$.store.book[:2]');
const last = jp.query(data, '$.store.book[-1:]');
const reversed = jp.query(data, '$.store.book[::-1]');

Slice syntax follows Python-like start:end:step behavior. String values are not sliced as character arrays.

Select several fields or indicesselect-union

const twoBooks = jp.query(data, '$.store.book[0,2]');
const fields = jp.query(data, '$.store.bicycle["color","price"]');

Unions remove duplicate results rather than concatenating duplicates, one documented difference from some older implementations.

Query keys that are not identifiersquote-property-name

const value = jp.query(record, '$["display-name"]');
const currency = jp.query(record, '$["€"]');

Use quoted bracket notation for punctuation or non-ASCII keys. Unsafe keys such as __proto__, constructor, and prototype are rejected in 1.3.0.

Return concrete paths instead of valuesget-match-paths

const paths = jp.paths(data, '$..author');
// Example: ['$', 'store', 'book', 0, 'author']

Each result is a key array rooted with $. Keep array indices as numbers if you later pass the path back to value or stringify.

Pair each value with its concrete pathget-nodes

const nodes = jp.nodes(data, '$.store.book[*].price');
for (const { path, value } of nodes) {
  console.log(jp.stringify(path), value);
}

nodes is useful when duplicate values must still be distinguished by location. The returned value references the original object graph.

Read or replace the first matching valueread-write-value

const oldPrice = jp.value(data, '$.store.book[0].price');
const newPrice = jp.value(data, '$.store.book[0].price', 9.5);

The three-argument form mutates the original object and only changes the first match. For a missing simple path, it can create intermediate objects or arrays.

Replace every matching valuetransform-matches

const changed = jp.apply(data, '$.store.book[*].price', (price) => {
  return Math.round(price * 100);
});

apply mutates data in place and returns nodes containing updated values. Clone the object first when callers expect immutability.

Inspect and rebuild a path expressionparse-stringify-path

const parsed = jp.parse('$..author');
const expression = jp.stringify(parsed);
const concrete = jp.stringify(['$', 'store', 'book', 0, 'author']);

stringify accepts either parsed components or a concrete key array. It is useful for logging paths returned by paths or nodes.

Alternatives

PackageRegistryPick it when
jsonpath-plusnpmYou need a more feature-rich JSONPath implementation with modern module support and configurable result types
jmespathnpmYou want a cross-language query language focused on projections and transformations rather than in-place mutation
jsonatanpmYou need a richer expression language for querying, calculation, aggregation, and reshaping JSON data