Skip to main content

Using the Go Host SDK

Check your installation

Please be sure you've installed Extism before continuing with this guide.

1. Install the Go module

Install via go get:

go get

2. Import the module and use the APIs

Count Vowels Plugin

code.wasm in this example is our example plugin that counts vowels. If you want to run this, download it first and set the path:

curl > code.wasm
package main

import (


func main() {
ctx := extism.NewContext()
defer ctx.Free() // this will free the context and all associated plugins

// set some input data to provide to the plugin module
var data []byte
if len(os.Args) > 1 {
data = []byte(os.Args[1])
} else {
data = []byte("testing from go -> wasm shared memory...")

manifest := extism.Manifest{Wasm: []extism.Wasm{extism.WasmFile{Path: "code.wasm"}}}

// NOTE: if you encounter an error such as:
// "Unable to load plugin: unknown import: wasi_snapshot_preview1::fd_write has not been defined"
// change `false` to `true` in the following function to provide WASI imports to your plugin.
plugin, err := ctx.PluginFromManifest(manifest, []Function{}, false)
if err != nil {

// use the extism Go library to provide the input data to the plugin, execute it, and then
// collect the plugin state and error if present
out, err := plugin.Call("count_vowels", data)
if err != nil {

// "out" is []byte type, and the plugin sends back json, so deserialize it into a map.
// expect this object: `{"count": n}`
var dest map[string]int
json.Unmarshal(out, &dest)

fmt.Println("Count:", dest["count"])

Host Functions

It is also possible to create functions to expose additional functionality from the host by using Host Functions. The first step is to declare it using EXTISM_GO_FUNCTION and define a function with the proper signature:

Count Vowels Plugin

To run this example, use the version of the count vowels plugin with the example host function:

curl > code.wasm
#include <extism.h>
import "C"

//export hello_world
func hello_world(plugin unsafe.Pointer, inputs *C.ExtismVal, nInputs C.ExtismSize, outputs *C.ExtismVal, nOutputs C.ExtismSize, userData uintptr) {
fmt.Println("Hello from Go!")
s := cgo.Handle(userData)
inputSlice := unsafe.Slice(inputs, nInputs)
outputSlice := unsafe.Slice(outputs, nOutputs)

// Get memory pointed to by first element of input slice
p := extism.GetCurrentPlugin(plugin)
mem := p.Memory(extism.ValGetUInt(unsafe.Pointer(&inputSlice[0])))

outputSlice[0] = inputSlice[0]

Then add it to the plugin when it's created:

// Create host function
f := extism.NewFunction("hello_world", []extism.ValType{extism.I64}, []extism.ValType{extism.I64}, C.hello_world, "Hello again!")
defer f.Free()
plugin, err := ctx.PluginFromManifest(manifest, []Function{f}, false)

Other Documentation

See the module documentation at:

Need help?

If you've encountered a bug or think something is missing, please open an issue on the Extism GitHub repository.

There is an active community on Discord where the project maintainers and users can help you. Come hang out!