JSONPath Plus keeps the original JSONPath operators and adds a few
A fork of JSONPath from http://goessner.net/articles/JsonPath/
At a glance
- What is it?
- jsonpath-plus is a JavaScript implementation of JSONPath that stays compliant with the original specification while adding parent and property-name selectors, type selectors, escaping and evaluation sandboxing. It suits Node and browser projects that need to query JSON, and its README says it is not being actively maintained.
- Who is it for?
- Adopt jsonpath-plus if you need a JSONPath implementation in JavaScript that keeps the original operators working and adds parent, property-name and type selectors, and if your use of path expressions is under your own control. Do not adopt it for a project that will be maintained by the project, because the README states the project is not currently being actively maintained and that the maintainers are not looking to make fixes or add features themselves.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A fork that adds operators without breaking the original ones
jsonpath-plus is a JavaScript implementation of JSONPath, forked from the original JSONPath by Stefan Goessner, and the project's own description of its scope is precise. It is compliant with the original jsonpath spec, and it expands on the original specification to add some additional operators and makes explicit some behaviors the original did not spell out.
That second half is what makes this fork interesting rather than a straight reimplementation. The original JSONPath was described in an article, and a great deal of its behaviour was left implicit, so two conforming implementations could disagree on edge cases. Making those behaviours explicit is a change that is invisible until the two implementations disagree, which is exactly the kind of bug that costs an afternoon.
The added operators are the concrete part. There is ^ for grabbing the parent of a matching item, and ~ for grabbing property names of matching items as an array. There are type selectors for the basic JSON types, @null(), @boolean(), @number(), @string(), @array() and @object(), plus @integer(), the compound @scalar() type, @other() usable together with a user-defined otherTypeCallback, and the non-JSON types @undefined(), @function() and @nonFinite() for when you are querying JavaScript objects rather than parsed JSON.
Within filters there are shorthand selectors: @path, @parent, @property, @parentProperty and @root. There is escaping, with a backtick for escaping a remaining sequence and the @['...'] and ?@['...'] syntax for escaping special characters within property names in filters. And $.. means getting all parent components.
The last two features are the ones that matter for anything beyond a toy. A path expression that can select a parent lets you modify what it matched, which is why the resultType option can return the parent object or the parent's property name.
Result types turn a query into a path, a pointer or a parent
The resultType option is the most consequential design decision in the library, and it is easy to overlook because the default behaviour is the obvious one.
The resultType property defaults to value, and it can be a case-insensitive form of value, path, pointer, parent or parentProperty. Those determine respectively whether to return the results as the values of the found items, as their absolute paths, as JSON Pointers to the absolute paths, as their parent objects, or as their parent's property name. If set to all, all of these types are returned on an object with the type as the key name.
So the same query can be answered in five different shapes. That is a much larger deal than it looks, because the choice determines what you can do with the result. A path is a location you can log or store, a JSON Pointer is a location you can hand to a patch operation, a parent object is something you can modify, and a parent property name is a key you can rename.
The feature list also mentions utilities for converting between paths, arrays and pointers, which is the missing half of that story. If you can query by path and you can query by pointer, and there is a converter, then a tool that speaks one can be driven from the other.
The other feature in the same area is that in addition to the queried values, the library can return various meta-information including paths or pointers to the value, as well as the parent object and parent property name, to allow for modification. That last clause is the point. JSONPath as a query language is read-only by nature, and the parent and parentProperty results are what turn it into something you can write with.
The whole call signature is short:
const result = JSONPath([options,] path, json, callback, otherTypeCallback);The path, json, callback and otherTypeCallback arguments can alternatively be expressed, along with any of the other available properties, on the options object. So the positional form is a convenience and the options form is the real interface.
The sandbox option exists because JSONPath permits code evaluation
This is the part of the library that a security review should care about most, and the library is upfront about it.
The feature list includes an option to prevent evaluations permitted in the original spec, or supply a sandbox for evaluated values. The sandbox property defaults to an empty object, and it is a key-value map of variables to be available to code evaluations such as filtering expressions. The README also notes that the current path and value will be available to those expressions.
The issue is that JSONPath's filter syntax, in its original form, is not a restricted expression language. A filter can contain arbitrary JavaScript, which means a JSONPath expression can become a function call into the surrounding environment. If a path expression ever comes from outside your program, from a configuration file, from a user, or from a remote API, then an untrusted path expression is a remote code execution vector.
That is why the two options exist. One is to prevent evaluations, which means filters that would need to evaluate code fail rather than run it. The other is to supply a sandbox, which means the evaluated code sees only the variables you chose to expose, plus the current path and value.
The same caution applies to the callback. The result contains all items found, optionally wrapped into an array, whereas the callback can be used if you wish to perform some operation as each item is discovered, with the callback function being executed 0 to N times depending on the number of independent items to be found. The callback is your own code, so it is not the risk; the path expression is.
The other callback, otherTypeCallback, is tied to the @other() type selector and lets you define what counts as the other type for a given value.
The autostart property, defaulting to true, is a smaller thing. If it is supplied as false, one may call the evaluate method manually, which matters if you want to construct the evaluator once and reuse it, or if you want to control when a sandbox is applied.
Node, browser, UMD and ESM builds, plus a CLI
The packaging is thorough, and the README documents each entry point separately because they are genuinely different.
The install is:
npm install jsonpath-plusIn Node, the CommonJS form is a require:
const {JSONPath} = require('jsonpath-plus');
const result = JSONPath({path: '...', json});For a browser you can include the UMD build directly, with no Browserify magic necessary, and the README shows the script tag and the global call:
<script src="node_modules/jsonpath-plus/dist/index-browser-umd.cjs"></script>
<script>
const result = JSONPath.JSONPath({path: '...', json: {}});
</script>For modern browsers there is an ES module import from the browser ESM build, and for bundlers such as Rollup you import the package name directly, with the note that mainFields should include browser for browser builds, while for Node the default, which checks module, should be fine.
The package.json exports map confirms the matrix. The root export has browser, umd, import, require and default conditions, each pointing at a different file in dist/, and each with its own TypeScript declaration file. There is also a named export for the package.json itself and two subpath exports for javascriptTypes.js and structuredCloningTypes.js, each with its own types and import conditions. The main field points at dist/index-node-cjs.cjs and the top-level types at dist/jsonpath.d.ts.
There is also a command line interface, since package.json declares bin entries for both jsonpath and jsonpath-plus, both pointing at ./bin/jsonpath-cli.js. A CLI for a query language is what you want when you are exploring a document rather than embedding the library.
The repository has a demo/ directory with an index.html and index.js, a dist/ directory checked in, a rollup.config.js for the build, a .babelrc.json, typedoc.json for the API documentation and an eslint.config.js. The type definitions are generated, so the API surface is documented in a form that stays in step with the code.
The maintenance notice is the most important line in the README
The README carries a notice in bold, and it is the first thing a serious adopter has to weigh.
It says: this project is not currently being actively maintained. We may accept well-documented PRs or some simple updates, but are not looking to make fixes or add new features ourselves.
That is an unusual thing to find in the README of a package, and it should be taken at face value. The distinction the notice draws is precise. Well-documented pull requests and simple updates may be accepted, so a small fix or a new operator is a realistic contribution. But the maintainers are not going to triage a bug report for you, chase a regression, or design a feature.
The repository activity is consistent with that notice. The last push was on 2026-10-13 and the repository is not archived, so work is still happening, but the recent release tags are v10.4.1 on 2026-06-25, v10.4.0 on 2026-02-16 and v10.3.0 on 2025-02-14, while the version in package.json reads 11.2.1. That gap between the tagged line and the manifest version tells you the 11.x work is not being cut as tags.
The licence is a custom one that GitHub cannot classify, with the LICENSE file in the repository as the authoritative text, and there is a licenseInfo.json in the repository root alongside a SECURITY.md for reporting vulnerabilities and a CHANGES.md. There is also a Snyk badge for known vulnerabilities in the README, which is a reasonable thing for a library that evaluates expressions to display.
So the practical reading is that this is a stable library that its maintainers have stepped back from. That is a perfectly good thing to depend on if you need the features it has. It is a bad thing to depend on if you need a new operator, a security fix, or a maintained issue tracker, and the readme's own words are the reason to know that before you start rather than after.
Editorial conclusion
Adopt jsonpath-plus if you need a JSONPath implementation in JavaScript that keeps the original operators working and adds parent, property-name and type selectors, and if your use of path expressions is under your own control. Do not adopt it for a project that will be maintained by the project, because the README states the project is not currently being actively maintained and that the maintainers are not looking to make fixes or add features themselves. Before you depend on it, read the sandbox option, because the original specification permits evaluations that execute code, and pin the version you test against, since the recent release tags are on the 10.x line while package.json reads 11.2.1.
Frequently asked questions
How do I install and use jsonpath-plus?
Run npm install jsonpath-plus, then in Node use const {JSONPath} = require('jsonpath-plus') and call JSONPath({path: '...', json}). The full signature is JSONPath([options,] path, json, callback, otherTypeCallback), and the arguments can also be supplied on the options object.
Which operators does jsonpath-plus add to the original JSONPath?
It adds ^ for the parent of a matching item, ~ for property names as an array, type selectors such as @null(), @boolean(), @number(), @string(), @array(), @object(), @integer(), @scalar() and @other(), the @path, @parent, @property, @parentProperty and @root filter shorthands, and escaping with a backtick and the @['...'] syntax.
Is jsonpath-plus safe to use with untrusted path expressions?
Not by default, because the original spec permits evaluations in filters. The library offers an option to prevent evaluations permitted in the original spec, or to supply a sandbox, which is a key-value map of variables available to code evaluations such as filtering expressions.
Can jsonpath-plus return the parent of a matched value so I can modify it?
Yes. The resultType option accepts value, path, pointer, parent or parentProperty, and setting it to all returns every type keyed by name. The parent and parentProperty forms return the parent object and the parent's property name, which is what allows modification.
Is jsonpath-plus still maintained?
The README says plainly that the project is not currently being actively maintained, that well-documented pull requests or simple updates may be accepted, and that the maintainers are not looking to make fixes or add new features themselves. The last push was on 2026-10-13 and the recent tags are on the 10.x line while package.json reads 11.2.1.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jsonpath-plus-jsonpath)Was this useful?