Risor is a fast, embeddable scripting language for Go applications.
Add dynamic expressions, filters, and user-defined logic to your Go programs without embedding a heavy runtime like V8 or Python. Expressions compile to bytecode and run on a lightweight VM. Pure Go, minimal dependencies.
Risor fills the gap between hardcoded logic and a full language runtime. It's for Go developers who need to evaluate user-provided expressions, rules, or small scripts safely at runtime.
// Expression evaluation: access control, validation rules
user.role == "admin" || resource.ownerId == user.id
// String templating: dynamic messages with embedded expressions
`Hello, ${user.name}! Your order ships ${order.shipDate}.`
// Configuration logic: safe navigation with fallbacks
config?.defaults?.theme ?? "light"
// Data transformation: filter, map, reduce
orders.filter(o => o.status == "pending").map(o => o.total).reduce((a, b) => a + b, 0)
go get github.com/deepnoodle-ai/risor/v2
Embedding is straightforward. By default, the environment is empty (secure by
default). Add the standard library with risor.Builtins():
import "github.com/deepnoodle-ai/risor/v2"
env := risor.Builtins()
env["user"] = currentUser
env["resource"] = requestedResource
allowed, err := risor.Eval(ctx,
`user.role == "admin" || resource.ownerId == user.id`,
risor.WithEnv(env),
)
Go primitives, slices, and maps convert automatically.
Risor is designed for scenarios where a Go application needs to evaluate user-provided or externally-defined logic at runtime:
order.total > 100 && customer.tier == "gold" that change frequently without redeploymentThe common pattern: a compiled Go host handles performance-critical work and exposes an API surface to Risor for flexible, safe, easy-to-change logic.
Risor is not a general-purpose programming language. It's not trying to replace Python or TypeScript for writing applications. There is no package manager, no module imports, and no third-party ecosystem — by design.
Extension happens through Go code: you add builtin functions, pass data into the script context, and read results back out. This keeps the core small and lets each application tailor Risor to its needs.
This is Risor v2, a major evolution focused entirely on the embedded scripting use case. v1 also served DevOps scripting, cloud tooling, and CLI usage. v2 narrows the focus to doing one thing well: giving Go developers a safe, fast way to evaluate user-provided expressions and scripts at runtime.
Implementations for TypeScript and Rust host programs are being prototyped, with good initial results.
Risor v1 remains available at tag v1.8.1.
#risor on Gophers Slack$ claude mcp add risor \
-- python -m otcore.mcp_server <graph>