Tengo is a small, dynamic, fast, secure script language for Go.
Tengo is fast and secure because it's compiled/executed as bytecode on stack-based VM that's written in native Go.
/* The Tengo Language */ fmt := import("fmt") each := func(seq, fn) { for x in seq { fn(x) } } sum := func(init, seq) { each(seq, func(x) { init += x }) return init } fmt.println(sum(0, [1, 2, 3])) // "6" fmt.println(sum("", [1, 2, 3])) // "123"Test this Tengo code in the Tengo Playground
- Simple and highly readable Syntax
- Dynamic typing with type coercion
- Higher-order functions and closures
- Immutable values
- Securely Embeddable and Extensible
- Compiler/runtime written in native Go (no external deps or cgo)
- Executable as a standalone language / REPL
- Use cases: rules engine, state machine, data pipeline, transpiler
| fib(35) | fibt(35) | Language (Type) | |
|---|---|---|---|
| Tengo | 2,315ms | 3ms | Tengo (VM) |
| go-lua | 4,028ms | 3ms | Lua (VM) |
| GopherLua | 4,409ms | 3ms | Lua (VM) |
| goja | 5,194ms | 4ms | JavaScript (VM) |
| starlark-go | 6,954ms | 3ms | Starlark (Interpreter) |
| gpython | 11,324ms | 4ms | Python (Interpreter) |
| Yaegi | 11,715ms | 10ms | Yaegi (Interpreter) |
| otto | 48,539ms | 6ms | JavaScript (Interpreter) |
| Anko | 52,821ms | 6ms | Anko (Interpreter) |
| - | - | - | - |
| Go | 47ms | 2ms | Go (Native) |
| Lua | 756ms | 2ms | Lua (Native) |
| Python | 1,907ms | 14ms | Python2 (Native) |
* fib(35): Fibonacci(35)
* fibt(35): tail-call version of Fibonacci(35)
* Go does not read the source code from file, while all other cases do
* See here for commands/codes used
go get github.com/d5/tengo/v2 A simple Go example code that compiles/runs Tengo script code with some input/output values:
package main import ( "context" "fmt" "github.com/d5/tengo/v2" ) func main() { // create a new Script instance script := tengo.NewScript([]byte( `each := func(seq, fn) { for x in seq { fn(x) } } sum := 0 mul := 1 each([a, b, c, d], func(x) { sum += x mul *= x })`)) // set values _ = script.Add("a", 1) _ = script.Add("b", 9) _ = script.Add("c", 8) _ = script.Add("d", 4) // run the script compiled, err := script.RunContext(context.Background()) if err != nil { panic(err) } // retrieve values sum := compiled.Get("sum") mul := compiled.Get("mul") fmt.Println(sum, mul) // "22 288" }Or, if you need to evaluate a simple expression, you can use Eval function instead:
res, err := tengo.Eval(ctx, `input ? "success" : "fail"`, map[string]interface{}{"input": 1}) if err != nil { panic(err) } fmt.Println(res) // "success"- Language Syntax
- Object Types
- Runtime Types and Operators
- Builtin Functions
- Interoperability
- Tengo CLI
- Standard Library
- Syntax Highlighters: VSCode, Atom, Vim
- Why the name Tengo? It's from 1Q84.