> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ubiquex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Plugins Overview

> How ubx engine plugins work — architecture, discovery, the gRPC protocol, and the official plugins.

Most ubx execution engines are plugins: a standalone binary that communicates with the ubx CLI over gRPC. The `native` engine is the exception — it runs in-process in core and is not a plugin.

## Architecture

```
ubx CLI (gRPC client)
  │
  │  Handshake → Schema → Compile → Plan → Apply → Destroy
  ▼
Plugin binary (ubx-plugin-<name>, gRPC server)
  │
  │  Compile → artifact_uri
  │  Plan    → structured diff
  │  Apply   → ProgressEvent stream
  │  Destroy → ProgressEvent stream
  ▼
Cloud Provider API
```

Core passes the compiled stack as `CompileRequest.ir_json` (JSON-serialised IR) with an `ir_schema_version`. Each plugin unmarshals the IR into its own local types — there is no shared SDK. The contract lives in `ubx-plugin-protocol` (Protocol Buffers / gRPC); any binary that implements `ubx.plugin.v1.PluginService` can be a ubx engine. See the [protocol reference](/v1/plugins/protocol) for all six RPCs.

## Plugin discovery

Core resolves a plugin binary by searching in order:

1. `~/.ubx/plugins/<name>/ubx-plugin-<name>` — installed via `ubx plugin install`
2. `ubx-plugin-<name>` on `$PATH`

## Plugin launch and lifecycle

Core launches the plugin binary with `UBX_PLUGIN_LAUNCH=1` in its environment. The plugin binds a random loopback TCP port and prints `UBX_PLUGIN_ADDR=127.0.0.1:<port>` to stdout. Core dials that address over insecure gRPC (loopback only) and calls `Handshake` first to negotiate protocol version `"1.0"`.

One plugin process serves one CLI invocation. When the invocation finishes, core sends `SIGINT` and, if the process has not exited within 5 seconds, `SIGKILL`.

## Official plugins

| Plugin                                        | Engine    | Generates                                                 |
| --------------------------------------------- | --------- | --------------------------------------------------------- |
| [ubx-plugin-pulumi](/v1/plugins/pulumi)       | Pulumi    | Python, TypeScript, or Go program → Pulumi Automation API |
| [ubx-plugin-terraform](/v1/plugins/terraform) | Terraform | `main.tf` → `terraform` CLI                               |
| [ubx-plugin-opentofu](/v1/plugins/opentofu)   | OpenTofu  | `main.tf` → `tofu` CLI                                    |

The core typechecker accepts `native`, `pulumi`, `terraform`, and `opentofu` as engine names. The `native` engine runs in-process (no plugin subprocess); the others dispatch to the matching plugin binary.

## Installing plugins

```bash theme={"theme":"css-variables","languages":{"custom":["/languages/xcl.json"]}}
ubx plugin install pulumi
ubx plugin install terraform
```

From a GitHub release, or from a local binary:

```bash theme={"theme":"css-variables","languages":{"custom":["/languages/xcl.json"]}}
ubx plugin install github://org/repo@v1.2.3
ubx plugin install file://./path/to/ubx-plugin-myengine
```

## Plugin lock file

After installing, ubx records each plugin's source and SHA256 in `.ubx/plugin.lock`.

## Writing a custom plugin

See [Writing a Plugin](/v1/plugins/writing-plugin). Custom plugins implement the same `ubx.plugin.v1.PluginService` gRPC service as the official plugins.
