jsonata

A lightweight query and transformation language for filtering, mapping, and reshaping JSON data with concise, path-based expressions.

Library
npm
v2.2.2
2,687stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
71/100Good
Development Activity52
Maintenance56
Community76
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
85/100Excellent
Architecture82
Code Quality88
Innovation78
Learning Curve90

JSONata is a lightweight, JSON-native query and transformation language that lets you navigate, filter, aggregate, and reshape JSON documents using compact, path-based expressions instead of imperative code. Inspired by XPath’s role for XML, it treats JSON as its native data model, letting a single expression string select nested fields, apply predicates, and pipe values through a large library of built-in string, numeric, array, and object functions.

The reference implementation is a pure JavaScript library with zero runtime dependencies, an async-first evaluator, and dedicated browser bundles alongside the Node.js package, making it equally suited to server-side data mapping, API request/response transformation, or client-side reshaping of fetched data before rendering. It’s maintained by IBM and widely embedded as the expression/mapping language inside integration and low-code (iPaaS) platforms, letting end users define data transformations declaratively instead of writing custom mapping code per integration.

What You Get

  • A path-based expression syntax for selecting and filtering nested JSON fields without writing traversal code by hand
  • A large built-in function library covering string, numeric, array, object, date/time, and aggregation operations
  • An async-first evaluator supporting both Promise-based and legacy callback-based evaluation, plus custom function registration via registerFunction
  • Prebuilt browser bundles (jsonata.js, jsonata-es5.js, and minified variants) alongside the standard npm package
  • TypeScript type definitions (jsonata.d.ts) for type-safe expression evaluation in TypeScript projects
  • An extensive, data-driven test suite (100+ JSON-defined test groups) covering the full expression language with 100% code coverage enforced in CI

Common Use Cases

  • Mapping API responses from one JSON schema into another without writing custom glue code
  • Extracting and aggregating fields from deeply nested JSON for reporting or analytics
  • Powering the data-mapping/expression layer inside low-code and integration (iPaaS) platforms
  • Filtering and reshaping JSON payloads inside serverless functions or API gateways
  • Client-side transformation of fetched JSON before rendering it in a UI

Under The Hood

Architecture src/jsonata.js exposes the jsonata(str, options) factory, which hands the expression string to a Pratt-style tokenizer/parser (src/parser.js) that produces an AST of typed nodes (path, binary, function, block, lambda, transform, etc.). The returned Expression’s evaluate(input, bindings) walks that AST through a single large evaluate() dispatch switch keyed on expr.type (src/jsonata.js), with a dedicated evaluateX function per node type. Environments created via createFrame chain together for variable/function lookup and carry depth and guardrail tracking (environment.base.depth, guardrails()) to protect against runaway expressions. The built-in function library (src/functions.js) and date/time helpers (src/datetime.js) are pure implementations invoked when a function node resolves to a built-in name, with argument arity/type checking handled by a dedicated signature-string parser (src/signature.js) rather than per-function boilerplate. Parser, evaluator, functions, and signature validation are cleanly separated into their own modules with no framework or DI container involved — the central evaluate switch is the one place a new AST node type would need to be wired in.

Tech Stack Pure JavaScript with zero runtime dependencies — package.json declares only devDependencies, and the entire engine, parser, and function library are self-contained under src/. Build tooling uses Babel plus regenerator to produce an ES5-compatible build and browserify to bundle a standalone browser build, minified with uglify-es. Tests run on Mocha and Chai (with chai-as-promised for the async evaluator) under nyc for coverage, and linting uses ESLint with the promise plugin. CI (.github/workflows/jsonata.yml) runs the full suite across Node 12 through 24, with a separate publish.yml workflow handling npm publishing via OIDC on tagged releases. TypeScript consumers get hand-maintained definitions in jsonata.d.ts; there’s no bundler-specific build step and no external runtime dependency surface to audit.

Code Quality Testing is data-driven rather than hand-written per case: test/run-test-suite.js reads over 100 JSON test-case groups plus shared datasets and dynamically generates Mocha assertions for each expression’s expected result or error code, a pattern that scales as language behavior grows without adding test boilerplate. Coverage is enforced at 100% statements/branches/functions/lines via nyc’s check-coverage script, an unusually strict bar. Error handling is explicit and typed: the evaluator throws structured error objects carrying code, position, and token fields (typed as JsonataError in jsonata.d.ts) rather than generic exceptions or silently swallowed failures. ESLint runs as a pretest step, so lint failures block npm test. The implementation itself is plain JS with JSDoc annotations rather than TypeScript, though the public type definitions are kept hand-maintained.

API Design The public surface is intentionally tiny — one factory function returning an Expression with evaluate, assign, registerFunction, and ast() — so getting started is a single import and a two-line call. The expression language itself is the real API-design bet: rather than exposing traversal, filtering, and aggregation as separate JS function calls, JSONata compresses them into one declarative string closer to XPath or JQ than to a fluent JS query builder, which is what makes it embeddable as user-facing configuration inside integration platforms rather than only as a library called by developers. Documentation is thorough and split by concern, with one file per operator/function category, a long-form tutorial, and a live sandbox (try.jsonata.org) linked from the README — lowering the learning curve for the expression syntax specifically, since the JS API itself is minimal enough to barely need documentation.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search