Risor vs Expr

Expr is a popular expression language for Go. It's fast, type-checks against host structs at compile time, and guarantees termination. It powers Argo Workflows, WunderGraph, and many production applications. Developers consistently report being "up and running in just a few minutes."

Expr evaluates single expressions. Risor adds variables, functions, pattern matching, and pipe operators in TypeScript-like syntax.

Where Expressions Run Out of Room

Expr (everything in one expression with ternaries):

(order.Total > 1000 ? 0.15 : (order.Total > 500 ? 0.10 : 0.05))
    * order.Total
    * (order.Customer.Tier == "enterprise" ? 0.9 : 1.0)

Risor:

let discount = if (order.total > 1000) { 0.15 }
    else if (order.total > 500) { 0.10 }
    else { 0.05 }
 
let multiplier = if (order.customer.tier == "enterprise") { 0.9 } else { 1.0 }
order.total * (1 - discount) * multiplier

Risor also supports user-defined functions. Expr doesn't:

function eligible(user) {
    user.active && user.age >= 18 && user.verified
}
 
function discount_rate(user) {
    match user.tier {
        "enterprise" => 0.20
        "pro" => 0.10
        _ => 0.0
    }
}
 
let rate = if (eligible(user)) { discount_rate(user) } else { 0.0 }
order.total * (1 - rate)

Comparison

PropertyExprRisor
ScopeSingle expressionsMulti-statement scripts
Variables / functionsNoYes
Pattern matching / pipesNoYes
SandboxedType-checked against provided envEmpty sandbox by default
SyntaxGo-likeTypeScript-like
Feature controlFixedHost chooses which features to enable
Type integrationCompile-time checking against Go structsNative host types via environment
LicenseMIT (with commercial "Pro" tier)Fully open source

Performance

Expr is the fastest runtime in our benchmarks for simple expressions: 0.08 µs versus Risor's 15.2 µs. Its compiled expression tree has almost no runtime dispatch.

Expr can also handle data processing, filtering and aggregating 10,000 records in 853 µs versus Risor's 4.20 ms. But Expr hits its ceiling at multi-step logic: no variables, no multi-statement scripts. Our business logic benchmark (two filters, a map, a reduce, and a conditional) can't be written in Expr at all.

Memory footprints are nearly identical for simple expressions: Expr at 1.9 KB, Risor at 2.2 KB.

ScenarioExprRisor
Simple expression (warm)0.08 µs15.2 µs
Data processing (10k records)853 µs4.20 ms
Business logic (500 records)N/A273 µs
Heap per instance (simple)1.9 KB2.2 KB

When to Choose Expr

  • Your logic fits in single expressions
  • You want compile-time type checking against Go structs
  • You want the most minimal integration surface

When to Choose Risor

  • You need variables, functions, or multi-step computation
  • You want TypeScript-like syntax and pipe operators
  • You want the host to control which language features are available
  • You want fully open source with no commercial tier

Learn More


Risor © 2026 Deep Noodle