Wasmo Docs

Plugin Structure

Your new Wasmo plugin generated from the UI wizard already includes some files and folders. Others, you will create yourself and add to Wasmo existing file structure.

Here’s how an Wasmo plugin is organized, and some files you will find in your new project.

Directories and Files

Wasmo leverages an opinionated files layout for your project. Every Wasmo plugin root should include the following files:

Common files

  • config - List of built versions (auto-generated)

  • *.log - Last run log files (auto-generated)

  • *wasm - List of released WASM (auto-generated)

Javascript/Typescript plugin

  • esbuild.(js|ts) - A bundler configuration file (required)

  • index.(js|ts) - Entrypoint of the plugin (required)

  • plugin.d.ts - Wasm interface for our plug-in (required)

  • *.(js|ts) - Your project source code

  • package.json - The plugin manifest (required)

Go plugin

  • main.go - Entrypoint of the plugin (required)

  • types.go - List of types to deal with Otoroshi integration

  • host.go - List of functions to deal with Otoroshi integration

  • *.go - Your project source code

  • go.mod - The plugin manifest (required)

Rust plugin

  • lib.rs - Entrypoint of the plugin (required)

  • types.rs - List of types to deal with Otoroshi integration

  • host.rs - List of functions to deal with Otoroshi integration

  • *.rs - Your project source code

  • Cargo.toml - The plugin manifest (required)

Opa plugin

  • policies.rego - Entrypoint of the plugin (required)

  • package.json - The plugin manifest (required)

Manifest content

The structure of the manifest files differs depending on the language.

The only common fields are the plugin-name and the plugin-version. Wasmo use these fields to generate the WASM binaries with the name: <plugin-name>-<plugin-version>-dev.wasm. You may have noticed the -dev. Wasmo supports the generation of both versions:

  • 1.0.0-dev: generated by the hammer icon, can be override any times (mutable)

  • 1.0.0: generated by the rocket icon, can't be override (immutable)

The minimum information required by language should be:


  "name": "<plugin-name>",
  "version": "<plugin-version>",
  "devDependencies": {
    "esbuild": "^0.17.9" 


module <plugin-name>/<plugin-version>

go 1.21

require github.com/buger/jsonparser v1.1.1 // indirect


name = "<plugin-name>"
version = "<plugin-version>"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
wasi = false

extism-pdk = "1.0.1"
serde = "1.0.152"
serde_json = "1.0.91"

crate_type = ["cdylib"]
path = "src/lib.rs"

Open Policy Agent

  "name": "<plugin-name>",
  "version": "<plugin-version>",
  "metadata": {
    "entrypoint": "example/can_access"

The OPA manifest requires one more field: the metadata entrypoint. The entrypoint is read by OPA to execute the policy.