· 6 min read ·

When Porting an Interpreter Costs Less Than a Week of Compute: The JSONata Rewrite Story

Source: simonwillison

The news from Simon Willison’s link blog this week is deceptively simple: a team ported the JSONata interpreter in a day with AI help and cut $500,000 per year in compute costs. That framing, though, undersells what actually happened. This isn’t a story about AI writing code fast. It’s a story about a threshold being crossed in the economics of software rewrites.

What JSONata Is and Why It Runs Everywhere

JSONata is a query and transformation language for JSON, created by Andrew Coleman at IBM and now widely used across integration platforms, including Node-RED, IBM App Connect, and a large number of middleware products that grew out of the enterprise integration space. Where SQL is for relational tables and XPath is for XML trees, JSONata is for JSON documents. Its syntax is compact and expressive:

Account.Order.Product.(Price * Quantity)

That single expression navigates a JSON structure, finds all products across all orders, and computes a total for each. The language supports filtering, aggregation, user-defined functions, recursion, and a built-in standard library covering string manipulation, math, array operations, and more. It is Turing-complete.

The reference implementation is a JavaScript npm package, jsonata, and it is pure JavaScript all the way down: a hand-written lexer, a recursive-descent parser that builds an AST, and a tree-walking evaluator. For small documents in a Node.js process that’s already warm, this works fine. At the scale Vine was running it, it apparently did not.

The Cost Problem With Interpreted Interpreters

When you run a JSONata evaluation at high volume in a managed compute environment, you’re paying for several layers of overhead simultaneously. The JSONata evaluator walks a JavaScript AST. The V8 engine JIT-compiles and optimizes the JavaScript code that does that walking. The container or Lambda function that hosts the Node.js process has its own startup and memory costs. Each of these layers adds latency and CPU time.

For a team processing millions of JSON transformations per day, the difference between running that workload on a native binary and running it inside Node.js can easily reach six figures annually. The $500K figure Vine cited is consistent with a service handling hundreds of requests per second where each request involves non-trivial JSONata expressions over moderately sized documents. A compiled Go or Rust implementation doing the same work consumes a fraction of the CPU, which in cloud pricing terms translates directly to dollars.

This is not a new observation. Developers have known for years that JSONata’s JavaScript implementation carries overhead when deployed at scale. The question was always whether the rewrite cost was worth it.

Why JSONata Is an Unusually Good Candidate for AI-Assisted Porting

An interpreter has a structure that LLMs handle well: it’s a pipeline of clearly separated modules, each with defined inputs and outputs. The JSONata JavaScript source breaks naturally into:

  1. Tokenizer — converts the expression string into a stream of typed tokens
  2. Parser — converts the token stream into an AST with well-defined node types
  3. Evaluator — recursively walks the AST against an input JSON document
  4. Built-in function library — roughly 70 standalone functions with no shared state

This structure means that porting can proceed function by function, module by module, with the existing code as a direct specification for each unit. An LLM given the JavaScript source for $sum() can produce a semantically equivalent Go or Rust function with high reliability because the function is short, has no side effects, and its behavior is fully defined by its inputs and outputs.

The evaluator is more complex because it handles JSONata’s path navigation semantics, which has subtleties around sequences, singletons, and the way filtering interacts with nested arrays. But even this is tractable when approached incrementally with tests running at each step.

Manual ports of JSONata have existed for years. jsonata4java is a Java implementation from IBM that has been maintained for some time. Writing it took months of engineering effort. The AI-assisted version of the same task apparently took a day.

The Test Suite as a Specification

One thing that makes JSONata particularly suitable for verified porting is the quality of its test suite. The jsonata-js repository ships a comprehensive set of test cases covering edge cases in path navigation, sequence semantics, operator precedence, function behavior, and error conditions. There are hundreds of them.

For a port to be trustworthy, it needs to pass these tests. The test suite is effectively a formal specification for what JSONata means. A team doing an AI-assisted port can use this as a verification harness: generate a translation of each module, run the tests against the translated code, iterate on failures. The LLM doesn’t need to understand JSONata’s semantics from first principles; it needs to produce code that makes the tests pass. That is a much simpler problem.

This pattern generalizes. Any interpreter or transformation library with a good test suite is a candidate for AI-assisted porting with a built-in correctness check. The test suite you’ve been maintaining as a safety net for contributors is also, it turns out, a specification document that an LLM can work against directly.

The Economics Are Now Inverted

The interesting thing about the $500K saving is not the number itself but what it implies about the decision that was available before LLMs were useful coding assistants.

Suppose porting JSONata manually would take two senior engineers three months. At fully loaded cost, that’s somewhere around $150,000 to $200,000 in engineering time, depending on the organization. The compute savings of $500K/year means the manual rewrite pays back in under six months, which is a reasonable return. So why wasn’t it done years ago?

The answer is usually some combination of: the effort estimate carries high uncertainty, the two engineers have other priorities, the existing implementation works well enough that there’s no forcing function, and any sufficiently complex rewrite carries correctness risk that requires careful validation. The expected value calculation was positive but not compelling enough to displace other work.

An AI-assisted port that takes one day changes every variable in that calculation. The engineering time cost drops by roughly 60x. The uncertainty about effort evaporates. The correctness risk is bounded by the existing test suite. The forcing function suddenly appears because the project is small enough to fit between other work.

The $500K/year was always available. The cost of capturing it just dropped below the threshold where someone would actually do it.

What This Means for Other Embedded Interpreters

There are a lot of JSONatas out there. Every integration platform, workflow engine, rules engine, and ETL tool that processes user-defined expressions is running an interpreter of some kind. Many of those interpreters were written in whatever language the host application uses, even when a different runtime would be substantially cheaper for the evaluation-heavy workload.

JMESPath, the AWS query language, has a JavaScript reference implementation and ports to many languages, but not all of them are maintained at the same quality level. JsonPath implementations vary widely in correctness and performance across runtimes. Any bespoke expression language embedded in a SaaS product is a candidate for the same analysis Vine ran: what does this actually cost to run, and what would it cost to port, and do those numbers work now?

The argument against doing this has always been that porting an interpreter is a substantial, risky engineering project. That argument is weaker than it used to be.

A Note on What “In a Day” Means

It’s worth being precise about what a one-day port actually delivers. A working implementation that passes the existing test suite is not the same as a production-hardened implementation. Memory safety, error handling in edge cases, behavior on malformed input, and performance under adversarial inputs all require additional attention beyond making the test suite green.

The day-one port is a foundation, not a finished product. But it’s a verified foundation. Vine presumably spent additional time hardening it before cutting over production traffic, and those costs are not captured in the headline. What the AI assistance compressed was the hardest part: the initial translation from one language’s semantics to another’s, maintaining correctness across hundreds of test cases.

That’s a meaningful compression. The remaining work, validation and hardening, is work that engineers understand how to estimate and budget. The part that used to be unknowable, whether a port of this complexity would even converge on a correct result, is now answered on day one.

The $500K saving is real and the methodology is repeatable. The teams that will benefit most are the ones who already know which of their embedded interpreters are running in the wrong runtime. They’ve known for years. Now the math works.

Was this interesting?