Risor is a fast and flexible scripting language for Go developers and DevOps.
Its modules integrate the Go standard library, making it easy to use functions that you're already familiar with as a Go developer.
Scripts are compiled to bytecode and then run on a lightweight virtual machine. Risor is written in pure Go.
Documentation is available at risor.io.
You might also want to try evaluating Risor scripts from your browser.
Here's a short example of how Risor feels like a hybrid of Go and Python. This demonstrates using Risor's pipe expressions to apply a series of transformations:
array := ["gophers", "are", "burrowing", "rodents"]
sentence := array | strings.join(" ") | strings.to_upper
print(sentence)
Output:
GOPHERS ARE BURROWING RODENTS
You might want to head over to Getting Started in the documentation. That said, here are tips for both the CLI and the Go library.
If you use Homebrew, you can install the Risor CLI as follows:
brew install risor
Having done that, just run risor
to start the CLI or risor -h
to see
usage information.
Execute a code snippet directly using the -c
option:
risor -c "time.now()"
Start the REPL by running risor
with no options.
Build the CLI from source as follows:
git clone git@github.com:risor-io/risor.git
cd risor/cmd/risor
go install -tags aws,k8s,semver,vault .
Use go get
to add Risor as a dependency of your Go program:
go get github.com/risor-io/risor@v1.7.0
Here's an example of using the risor.Eval
API to evaluate some code:
package main
import (
"context"
"fmt"
"log"
"github.com/risor-io/risor"
)
func main() {
ctx := context.Background()
script := "math.sqrt(input)"
result, err := risor.Eval(ctx, script, risor.WithGlobal("input", 4))
if err != nil {
log.Fatal(err)
}
fmt.Println("The square root of 4 is:", result)
}
30+ built-in functions are included and are documented here.
Modules are included that generally wrap the equivalent Go package. For example,
there is direct correspondence between base64
, bytes
, filepath
, json
, math
, os
,
rand
, regexp
, strconv
, strings
, and time
Risor modules and
the Go standard library.
Risor modules that are beyond the Go standard library currently include
aws
, pgx
, uuid
, vault
, and k8s
.
It is trivial to embed Risor in your Go program in order to evaluate scripts that have access to arbitrary Go structs and other types.
The simplest way to use Risor is to call the Eval
function and provide the script source code.
The result is returned as a Risor object:
result, err := risor.Eval(ctx, "math.min([5, 2, 7])")
// result is 2, as an *object.Int
Provide input to the script using Risor options:
result, err := risor.Eval(ctx, "input | strings.to_upper", risor.WithGlobal("input", "hello"))
// result is "HELLO", as an *object.String
Use the same mechanism to inject a struct. You can then access fields or call methods on the struct from the Risor script:
type Example struct {
Message string
}
example := &Example{"abc"}
result, err := risor.Eval(ctx, "len(ex.Message)", risor.WithGlobal("ex", example))
// result is 3, as an *object.Int
Risor is designed to have minimal external dependencies in its core libraries.
You can choose to opt into various add-on modules if they are of value in your
application. The modules are present in this same Git repository, but must be
installed with go get
as separate dependencies:
Name | Path | Go Get Command |
---|---|---|
aws | modules/aws | go get github.com/risor-io/risor/modules/aws@v1.7.0 |
bcrypt | modules/bcrypt | go get github.com/risor-io/risor/modules/bcrypt@v1.7.0 |
carbon | modules/carbon | go get github.com/risor-io/risor/modules/carbon@v1.7.0 |
cli | modules/cli | go get github.com/risor-io/risor/modules/cli@v1.7.0 |
image | modules/image | go get github.com/risor-io/risor/modules/image@v1.7.0 |
jmespath | modules/jmespath | go get github.com/risor-io/risor/modules/jmespath@v1.7.0 |
k8s | modules/kubernetes | go get github.com/risor-io/risor/modules/kubernetes@v1.7.0 |
pgx | modules/pgx | go get github.com/risor-io/risor/modules/pgx@v1.7.0 |
s3fs | os/s3fs | go get github.com/risor-io/risor/os/s3fs@v1.7.0 |
semver | modules/semver | go get github.com/risor-io/risor/modules/semver@v1.7.0 |
sql | modules/sql | go get github.com/risor-io/risor/modules/sql@v1.7.0 |
template | modules/template | go get github.com/risor-io/risor/modules/template@v1.7.0 |
uuid | modules/uuid | go get github.com/risor-io/risor/modules/uuid@v1.7.0 |
vault | modules/vault | go get github.com/risor-io/risor/modules/vault@v1.7.0 |
These add-ons are included by default when using the Risor CLI. However, when
building Risor into your own program, you'll need to opt-in using go get
as
described above and then add the modules as globals in Risor scripts as follows:
import (
"github.com/risor-io/risor"
"github.com/risor-io/risor/modules/aws"
"github.com/risor-io/risor/modules/image"
"github.com/risor-io/risor/modules/pgx"
"github.com/risor-io/risor/modules/uuid"
)
func main() {
source := `"nice modules!"`
result, err := risor.Eval(ctx, source,
risor.WithGlobals(map[string]any{
"aws": aws.Module(),
"image": image.Module(),
"pgx": pgx.Module(),
"uuid": uuid.Module(),
}))
// ...
}
A Risor VSCode extension is already available which currently only offers syntax highlighting.
You can also make use of the Risor TextMate grammar.
There are two Makefile commands that assist with benchmarking and CPU profiling:
make bench
make pprof
Risor is intended to be a community project. You can lend a hand in various ways:
- Please ask questions and share ideas in GitHub discussions
- Share Risor on any social channels that may appreciate it
- Open GitHub issue or a pull request for any bugs you find
- Star the project on GitHub
Adding modules to Risor is a great way to get involved with the project. See this guide for details.
Please visit the GitHub discussions page to share thoughts and questions.
There is also a #risor
Slack channel on the Gophers Slack.
Check CREDITS.md.
Released under the Apache License, Version 2.0.
Copyright Curtis Myzie / github.com/myzie.