· 6 min read ·

Owning the Runtime: The Fork Maintenance Bill After the JSONata Rewrite

Source: hackernews

The Reco.ai writeup about porting JSONata with AI in a single day has generated a lot of commentary, most of it focused on two things: the one-day timeline and the $500K/year savings figure. Both are real, and both deserve the attention they have gotten. But the story the article does not tell is what comes after the celebration ends.

They now own a language runtime.

What JSONata Is

JSONata is a query and transformation language for JSON, created by Andrew Coleman at IBM and first open-sourced around 2016. The comparison to XPath for XML is the right mental model: JSONata navigates nested JSON structure, filters with predicates, aggregates sequences, and constructs entirely new output from input data. A basic expression:

Account.Order.Product[Price > 100].Description

filters products by price and extracts descriptions from a nested structure in one pass. The language extends this with higher-order functions ($map, $filter, $reduce), inline lambdas, a full string and math library, date formatting, regular expression support, and a type system that propagates undefined differently from null in ways that matter for correct evaluation.

The reference implementation is a tree-walking interpreter in JavaScript: it parses expressions with a Pratt parser, builds an AST, and walks that AST against the input document at evaluation time. It ships as an npm package and sees tens of millions of weekly downloads, most of them transitive from Node-RED, IBM App Connect, and AWS integrations.

The Performance Problem at Scale

The JavaScript interpreter is not fast. Every expression evaluation builds and garbage-collects intermediate JavaScript objects. The execution model is synchronous and single-threaded at its core. For a tool originally designed for integration platform development tooling, those tradeoffs were fine. At serverless scale, running JSONata evaluations per incoming event, they become expensive.

Reco.ai was running JSONata-based policy evaluation across a high volume of incoming events from SaaS applications. At serverless billing rates, per GB-second on Lambda or equivalent, CPU-heavy workloads compound quickly. The $500K/year figure implies something in the range of tens of thousands of dollars per month in Lambda compute, which is consistent with processing millions of events daily through a Node.js runtime that spends most of its time in JSONata’s AST walker.

The case for porting is straightforward: move from an interpreted AST-walker in garbage-collected JavaScript to a compiled implementation in a language with predictable allocations, and the same evaluation load costs a fraction of the compute.

What Made the AI Port Tractable

There are prior JSONata ports going back to at least 2018. JSONata4Java from IBM itself. Multiple Go attempts. Python implementations. Most pass a portion of the test suite, stall on edge cases, and eventually go stale.

The difference with Reco.ai’s port was the methodology: use JSONata’s conformance test suite as the oracle, generate an implementation in a faster language with AI assistance, and iterate against failing tests until the suite passes. The AI made the mechanical translation fast and cheap. The test suite made correctness measurable at each step.

JSONata’s test suite is comprehensive enough to probe the semantics that tripped up prior implementations: the sequence type that is neither an array nor a scalar, the undefined propagation rules that differ from null semantics, the JavaScript-derived regex behavior that differs from RE2 or POSIX. If your implementation passes the full suite, you have high confidence it handles real-world expressions correctly. This is exactly the kind of machine-checkable standard that makes AI-assisted migration trustworthy rather than reckless.

The Second Decision

Here is what the writeup does not dwell on: Reco.ai now maintains a fork of the JSONata runtime.

JSONata development is active. The library ships new versions. Some contain bug fixes that affect evaluation semantics, edge cases in path resolution, or regressions in specific function behaviors. Some add new built-in functions. Occasionally a security-related fix addresses something like a ReDoS vulnerability on certain input patterns.

Every one of those upstream changes is now Reco.ai’s problem to track, evaluate, and port.

This is not a theoretical concern. Consider the practical shape of it:

  • A JSONata bug fix changes how a specific $lookup() behavior propagates through a nested object. Does Reco.ai’s port have the same bug? They need to check.
  • JSONata adds a new optional argument to an existing function. Customers start using it because the JSONata documentation says it works. The private port does not support it yet. A support ticket arrives.
  • JSONata tightens behavior around malformed expressions in a minor release. The private implementation silently accepts the same expression. A customer pipeline that should fail now silently returns the wrong result.

None of these are hypothetical; they are the normal lifecycle of a fork that does not merge upstream. The drift accumulates gradually until something breaks in production.

How to Manage Fork Drift

There are three credible strategies for managing this problem, each with different trade-offs.

The first is version pinning with explicit communication. Pick a JSONata version. Document that your implementation is compatible with that version only. Customers know what they are getting, and the maintenance burden is bounded: you track security patches against your pinned version, not the full upstream changelog.

AWS took a version of this approach with Step Functions and EventBridge. AWS Step Functions added native JSONata support in late 2024 with the feature set explicitly scoped and documented. Customers know which JSONata behaviors they can rely on. AWS does not chase every upstream release.

The second is upstream-first maintenance, tracking the JSONata changelog and porting relevant changes on a regular cadence. This keeps the implementation current but requires genuine ongoing investment, roughly proportional to how actively JSONata evolves. For a small team, this competes directly against product development.

The third is open-sourcing the port and letting the community share the maintenance burden. A production-quality Go or Rust JSONata implementation would attract contributors from the Node-RED and App Connect ecosystems, all of whom share the same interest in faster evaluation. The trade-off is losing private competitive advantage and acquiring community management overhead. The precedent exists: PyPy emerged from a research project and survived because a community adopted it; JRuby has been maintained for over fifteen years by contributors with a shared interest in running Ruby on the JVM. An open-source JSONata port at this quality level would likely find a home.

What the Economics Actually Look Like

The $500K/year savings is a year-one number. The right way to evaluate this decision is over a three-to-five year horizon.

Year one: the port is cheap (one day of AI-assisted work plus validation) and the savings are immediate and large.

Year two: the port needs maintenance. If upstream JSONata ships two or three significant releases, Reco.ai spends engineering time tracking and porting. Call it a week per year for a careful team. Against $500K in annual savings, that is trivial.

Year five: JSONata has shipped a new major version. The conformance suite has grown. The port has drifted in specific places. A customer is using a feature that was never implemented. The remediation effort is larger now.

The math still likely works. $500K per year is large enough that even a few weeks of annual maintenance effort stays well within the positive-ROI window. But the savings figure in the headline is not a fixed annual benefit. It is the gap between actual compute costs and what they would have been, and that gap can narrow if upstream features or security patches require substantial porting work.

The Broader Pattern

What Reco.ai did is a template for a specific class of decisions that are now much cheaper than they were two years ago: take a library with a well-specified conformance suite, port it to a faster runtime using AI for the mechanical translation, and use the test suite to validate correctness.

The right candidates share several properties. The library is well-specified with a comprehensive test suite. The evaluation semantics do not depend on external system state or global mutable behavior. The performance difference between the original runtime and the target language is large enough to justify ongoing maintenance. And the library’s upstream development pace is slow enough that fork drift stays manageable.

JSONata scored well on most of these criteria. The question for teams considering similar moves is whether their target library scores as well, and whether their savings estimate accounts for years two through five, not just year one.

A language port completed in a day is an impressive engineering outcome. Owning the resulting runtime indefinitely is a different kind of commitment. Both facts belong in the same analysis.

Was this interesting?