opencode-map
← guides/

Writing an opencode plugin

AdvancedLast updated: Oct 21, 2026

opencode plugins are JavaScript/TypeScript modules that hook into agent events and customize behavior — add tools, transform tool calls, inject context, react to session events. The official docs list a growing plugin ecosystem; this is how you join it.

Where plugins live

Two loading paths:

  • Local files — ~/.config/opencode/plugins/ (global) or .opencode/plugins/ (project). Loaded directly.
  • npm packages — listed in opencode.json; installed automatically with Bun at startup and cached under ~/.cache/opencode/node_modules/:
{ "plugin": ["opencode-copilot-plugin", "@my-org/custom-plugin"] }

The module shape

A plugin exports one or more plugin functions. Each receives a context object and returns a hooks object:

export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
  console.log("Plugin initialized!")
  return {
    // hook implementations
  }
}

The context gives you:

  • project — current project info
  • directory — current working directory
  • worktree — git worktree path
  • client — an opencode SDK client
  • $ — Bun’s shell API for running commands

Hooks and events

Hooks include tool interception points like tool.execute.before — e.g. sanitize a shell command before it runs:

import { escape } from "shescape"

export const Escape = async (ctx) => ({
  "tool.execute.before": async (input, output) => {
    if (input.tool === "shell") output.args.command = escape(output.args.command)
  },
})

An event hook subscribes to lifecycle events — command.executed, file.edited, file.watcher.updated, installation.updated, session/permission events and more (full list in the plugins doc; newer events include lsp.*, message.*, tui.* and tool.execute.after).

Dependencies and TypeScript

Local plugins can use npm packages: drop a package.json in your config directory (.opencode/package.json) and opencode runs bun install at startup.

For types, import Plugin from the official package:

import type { Plugin } from "@opencode-ai/plugin"

export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => ({
  // type-safe hooks
})

Publishing

  • A minimal plugin is a single .ts/.js file exporting a Plugin function — no scaffolding required; browse a small published plugin on the ecosystem page for a working skeleton.
  • Ship on npm as opencode-* (or a scoped name) so users can add it via the plugin config array — no manual install step.
  • Real examples to study: opencode-pty, opencode-dynamic-context-pruning, opencode-supermemory on the ecosystem page.

Further reading