~
The XPR playground evaluating items.filter(x => x.active).map(x => x.name) against a three-item JSON context, with the JavaScript, Python and Go runtimes each returning the identical result of Widget and Doohickey in 0.0ms, 1.6ms and 9.6ms respectively.
back to projects

oss project

Project status: stable

xpr-lang

A sandboxed expression language with near-byte-identical runtimes in TypeScript, Python, and Go.

3 runtimes 601 conformance tests 71 built-ins

npm
@xpr-lang/xpr
PyPI
xpr-lang
Go
github.com/xpr-lang/xpr-go
fig. 02
The XPR language specification page covering literals and operators, alongside a contents list running from arrow functions and let bindings through the pipe operator, regex functions and negative array indexing.
The spec is the source of truth all three runtimes are tested against.

Why I built it

Most expression languages for data pipelines are either too unsafe (full JavaScript with eval), too primitive (cron-style templates), or runtime- specific (you write your pipeline expression once for Python, again for Go). xpr-lang fills the gap: one syntax, three implementations, formal guarantees about safety, and conformance-tested behavior across runtimes.

Architecture highlights

  • Single source of truth: the EBNF grammar in xpr-lang/xpr is the authoritative spec. Each runtime parses to the same AST shape.
  • YAML conformance suite: 601 test cases driving identical behavior across TS/Python/Go, plus 71 built-in functions. CI on every PR.
  • Zero I/O surface: no file, network, or OS access; no import, no eval, no loops. Safe to evaluate untrusted user expressions.
  • Familiar syntax: arrow functions, pipe operator, optional chaining, destructuring, regex literals — if you know modern JS/Python, you can read xpr-lang.
  • Three runtimes: TypeScript (@xpr-lang/xpr), Python (xpr-lang), Go (github.com/xpr-lang/xpr-go).