Go Integration
Complete guide for embedding Scriptling in Go applications.
Choose by integration goal
- Evaluate scripts and exchange values: Start with Basics.
- Expose Go functions or classes quickly: Use the type-safe Builder API.
- Control conversion and performance directly: Use the Native API.
- Control which modules scripts can import: Read Library Registration and the Library Loader Chain.
- Run scripts that declare their requirements: Check their Script Metadata blocks before executing them.
- Extend the host out of process: See Embedding Plugins. If you want to run Scriptling itself as a server, use the CLI server guides instead.
Installation
go get github.com/paularlott/scriptlingQuick Start
package main
import (
"fmt"
"github.com/paularlott/scriptling"
"github.com/paularlott/scriptling/stdlib"
)
func main() {
// Create interpreter
p := scriptling.New()
// Register standard libraries
stdlib.RegisterAll(p)
// Execute Scriptling code
_, err := p.Eval(`x = 5 + 3`)
if err != nil {
fmt.Println("Error:", err)
}
}Focused examples on the pages below generally assume p has been initialized as shown here. Setup is repeated only when a registration or interpreter-lifecycle choice is part of the example.
Topics
- Basics - Creating interpreters, variable exchange, calling functions
- Native API - Direct object-level control
- Native Functions - Register individual Go functions
- Native Classes - Create custom classes with full control
- Native Libraries - Create libraries with functions and constants
- Builder API - Type-safe, cleaner syntax
- Builder Functions - Type-safe function builder
- Builder Libraries - Type-safe library builder
- Builder Classes - Type-safe class builder
- Builder Instantiation - Library templates with per-instance config
- Script Extensions - Extend using Scriptling code
- Embedding Plugins - Enable executable plugins in embedded applications
- Library Loader Chain - Flexible library loading from multiple sources
- Checking Script Requirements - Verify scripts’ inline metadata blocks before running them
- Documenting Extensions - Add help text to functions and libraries
- Library Registration - Register built-in libraries when embedding
- Linting - Code analysis for detecting syntax errors without execution
- GC Release Hooks - Best-effort cleanup hooks for Go-owned objects
Two Integration Approaches
Native API
Direct object-level control with predictable overhead:
p.RegisterFunc("add", func(ctx context.Context, kwargs object.Kwargs, args ...object.Object) object.Object {
a, _ := args[0].AsInt()
b, _ := args[1].AsInt()
return object.NewInteger(a + b)
})Builder API
Type-safe, cleaner syntax with automatic conversion:
fb := object.NewFunctionBuilder()
fb.FunctionWithHelp(func(a, b int) int {
return a + b
}, "add(a, b) - Add two numbers")
p.RegisterFunc("add", fb.Build())Performance Tips
- Choose a lifecycle deliberately - Reuse as-is only for one persistent script session; call
Reset()between unrelated jobs orClone()for isolated interpreters - Load Only Needed Libraries - Don’t load JSON/HTTP if not needed
- Batch Operations - Execute larger scripts rather than many small ones
- Pre-register Functions - Register all Go functions before execution
- Measure Hot Paths - Builder signatures are cached and common shapes use fast wrappers; compare Native and Builder APIs with your workload
// Reuse registrations while clearing script globals between unrelated jobs.
p := scriptling.New()
stdlib.RegisterAll(p)
for _, source := range scripts {
_, err := p.Eval(source)
p.Reset()
if err != nil {
return err
}
}For a stateful session, omit Reset() so globals and imports persist. See Interpreter lifecycle for ResetEnv and Clone choices.
Choosing Your Approach
| Use Case | Recommended Approach |
|---|---|
| Simple functions | Builder API |
| Rapid development | Builder API |
| Performance-critical code | Native API |
| Complex type handling | Native API |
| Reusing Scriptling code | Script Extensions |
| Building on Go libraries | Script Extensions |