From the Piko project ↗

Go, interpreted.

Run Go files as scripts, explore ideas in a REPL, or embed the interpreter in your Go application.

Open source · Apache 2.0 · Alpha

main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, pipit")
}
Terminal
$ pipit run main.go

Hello, pipit

No separate go build command.
Pipit compiles and executes the source for you.

Two ways to use it

In your terminal.
Inside your program.

Use the CLI to run Go files and try ideas in a REPL. Or add the library to a Go program and run Go source from it.

The command line

Go from the command line

Run a file, evaluate an expression, or work through an idea in a REPL that remembers your imports and declarations.

$ pipit eval -e '1 + 2 * 3'
7

$ pipit repl
Explore the CLI →
The Go library

Go inside your application

Evaluate source in your Go program. Expose host functions, reuse compiled programs, and configure execution limits.

interp := pipit.NewInterpreter()
value, err := interp.Eval(ctx, "1 + 2 * 3")
if err != nil {
    return err
}
Embed Pipit →
Why interpret Go?

Change behaviour
without a rebuild.

A new rule shouldn't need a new host binary. Let users write plugins, let your team change workflows, and keep the expensive work in compiled Go.

Connect scripts to your application →
plugin.goLoaded at runtime
package main

import "myapp/rules"

func main() {
    score := rules.Score("new-order")
    println(score)
}
Calls your compiled Gorules.Score("new-order")
You register rules.Score in the host. The plugin decides when to call it.

Load plugins at runtime

Compile a package of Go source files when you need it. Save the bytecode and run it again later, without rebuilding your application.

Compile and reuse packages →

Keep heavy lifting native

Interpreted code can call compiled Go functions you register. Keep performance-critical work in native code and use scripts to coordinate it.

Expose compiled Go →

Scripts in plain Go

Write custom rules, automation and plugins in Go, not a separate scripting language. Scripts can import the whole standard library, apart from unsafe, syscall, cgo and the runtime tooling packages.

Explore supported Go →

Keep state between runs

Use a session when later snippets need earlier imports and declarations, as the REPL does. Reset an interpreter to clear its state.

Retain state →
How we check it

What we test and publish.

Pipit is alpha. These are the checks we run, and the results are public.

Its compiler runs under itself

The self-hosting check runs Pipit's compiler inside Pipit on our test programs. It compares the bytecode with the native compiler's output, byte for byte.

Read the latest report →

Benchmarks with the method

We time Pipit against native Go, CPython, PyPy and four other Go-embeddable interpreters on 24 workloads. The method and raw results are published.

See the benchmarks →

A debugger in your editor or browser

pipit dap runs a Debug Adapter Protocol server, so editors can set breakpoints, inspect variables and step through a script. The playground has a debugger too.

Debugging with DAP →

It runs Doom

As an experiment, Pipit interprets a Go port of Doom in your browser. The browser build is the slowest form of Pipit, and the page explains why.

Play Freedoom →
Know what you're running

Limits and permissions.

Set timeouts, instruction-cost budgets and allocation caps. Gate selected network, file, process and environment operations so they need approval.

These controls run inside your process. They are not a sandbox, so run untrusted code with operating-system isolation as well.

Part of the
Piko project.

Pipit began inside the Piko web framework. Today, its interpreter lives in its own repository, ready to use from the command line or your application. This website is built with Piko.

Meet Piko ↗
Get started

Try it in your browser, or install the CLI.

Open the playground ↗Install Pipit →