MCPcopy Index your code
hub / github.com/deepnoodle-ai/risor

github.com/deepnoodle-ai/risor @v2.1.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v2.1.0 ↗ · + Follow
3,870 symbols 19,336 edges 233 files 1,121 documented · 29%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Risor

CI Go.Dev reference Apache-2.0 license

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)

Install

go get github.com/deepnoodle-ai/risor/v2

Go API

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.

Use Cases

Risor is designed for scenarios where a Go application needs to evaluate user-provided or externally-defined logic at runtime:

  • Workflow engines — Evaluate conditions and run small scripts at each step to decide branching, transform data, or trigger actions
  • Rules engines — Express business rules like order.total > 100 && customer.tier == "gold" that change frequently without redeployment
  • Expression evaluation — Dynamic filters, computed fields, validation rules, access control predicates
  • String templating — Interpolated strings with embedded expressions for notifications, reports, emails
  • Configuration logic — When static config (YAML, JSON) isn't enough but a full language is too much
  • Data transformation — User-defined transforms, enrichment, and filtering in data pipelines
  • Plugin & extension systems — Let users or tenants write small scripts that customize application behavior

The common pattern: a compiled Go host handles performance-critical work and exposes an API surface to Risor for flexible, safe, easy-to-change logic.

What Risor Isn't

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.

Documentation

Risor v2

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.

Contributing

License

Apache License 2.0

Extension points exported contracts — how you extend this code

FriendlyError (Interface)
FriendlyError is an interface for errors that have a human friendly message in addition to a the lower level default err [6 …
pkg/errors/errors.go
Node (Interface)
Node represents a portion of the syntax tree. All nodes have position information indicating where they appear in the so [43 …
pkg/ast/ast.go
Object (Interface)
Object is the interface that all object types in Risor must implement. [24 implementers]
pkg/object/object.go
Observer (Interface)
Observer is an interface for observing VM execution events. Implementations can be used for profiling, debugging, code c [3 …
pkg/vm/observer.go
ParserError (Interface)
ParserError is an interface that all parser errors implement. [2 implementers]
pkg/parser/errors.go
Validator (Interface)
Validator inspects an AST and returns validation errors. Validators should not modify the AST. [1 implementers]
pkg/syntax/validator.go
Option (FuncType)
Option configures a Risor compilation or execution.
risor.go
DocsOption (FuncType)
DocsOption configures documentation retrieval.
pkg/docs/docs.go

Core symbols most depended-on inside this repo

NewInt
called by 1191
pkg/object/int.go
NewString
called by 687
pkg/object/string.go
Run
called by 590
pkg/vm/vm.go
Value
called by 541
pkg/object/int.go
Parse
called by 515
pkg/parser/parser.go
String
called by 405
pkg/ast/ast.go
First
called by 306
pkg/parser/errors.go
Len
called by 297
pkg/object/object.go

Shape

Function 2,217
Method 1,325
Struct 279
Interface 20
TypeAlias 15
FuncType 14

Languages

Go100%
TypeScript1%
Python1%

Modules by API surface

pkg/parser/edge_cases_test.go113 symbols
pkg/vm/vm_test.go109 symbols
pkg/ast/expressions.go86 symbols
pkg/object/go_struct_test.go83 symbols
pkg/object/list_test.go73 symbols
risor_test.go72 symbols
pkg/compiler/compiler.go72 symbols
pkg/ast/literals.go65 symbols
pkg/ast/statements.go64 symbols
pkg/ast/ast_test.go60 symbols
tests/integration_test.go58 symbols
pkg/parser/expressions_test.go58 symbols

For agents

$ claude mcp add risor \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact