Skip to main content
Plugins allow you to extend OpenCode by hooking into various events and customizing behavior. You can create plugins to add new features, integrate with external services, or modify OpenCode’s default behavior. For examples, check out the plugins created by the community.

Use a plugin

There are two ways to load plugins.

From local files

Place JavaScript or TypeScript files in the plugin directory.
  • .opencode/plugins/ - Project-level plugins
  • ~/.config/opencode/plugins/ - Global plugins
Files in these directories are automatically loaded at startup.

From npm

Specify npm packages in your config file.
opencode.json
Both regular and scoped npm packages are supported. Browse available plugins in the ecosystem.

How plugins are installed

npm plugins are installed automatically using Bun at startup. Packages and their dependencies are cached in ~/.cache/opencode/node_modules/. Local plugins are loaded directly from the plugin directory. To use external packages, you must create a package.json within your config directory (see Dependencies), or publish the plugin to npm and add it to your config.

Load order

Plugins are loaded from all sources and all hooks run in sequence. The load order is:
  1. Global config (~/.config/opencode/opencode.json)
  2. Project config (opencode.json)
  3. Global plugin directory (~/.config/opencode/plugins/)
  4. Project plugin directory (.opencode/plugins/)
Duplicate npm packages with the same name and version are loaded once. However, a local plugin and an npm plugin with similar names are both loaded separately.

Create a plugin

A plugin is a JavaScript/TypeScript module that exports one or more plugin functions. Each function receives a context object and returns a hooks object.

Dependencies

Local plugins and custom tools can use external npm packages. Add a package.json to your config directory with the dependencies you need.
.opencode/package.json
OpenCode runs bun install at startup to install these. Your plugins and tools can then import them.
.opencode/plugins/my-plugin.ts

Basic structure

.opencode/plugins/example.js
The plugin function receives:
  • project: The current project information.
  • directory: The current working directory.
  • worktree: The git worktree path.
  • client: An opencode SDK client for interacting with the AI.
  • $: Bun’s shell API for executing commands.

TypeScript support

For TypeScript plugins, you can import types from the plugin package:
my-plugin.ts

Plugin API

Context

The plugin function receives a PluginInput context object:
  • client: SDK client for interacting with OpenCode’s API
  • project: Current project metadata
  • directory: Current working directory for the session
  • worktree: Git worktree root path
  • serverUrl: OpenCode server URL
  • $: Bun’s shell interface for executing commands

Hooks

Plugins return a Hooks object with event handlers. All hooks are optional.

Chat Hooks

chat.message: Modify messages before they’re sent to the LLM
chat.params: Modify LLM parameters (temperature, topP, topK)
chat.headers: Add custom headers to LLM requests

Tool Hooks

tool.execute.before: Intercept tool calls before execution
tool.execute.after: Modify tool results after execution
tool.definition: Modify tool definitions sent to the LLM
tool: Register custom tools

Command Hooks

command.execute.before: Modify commands before execution

Permission Hooks

permission.ask: Override permission decisions

Shell Hooks

shell.env: Inject environment variables into shell execution

Session Hooks

experimental.session.compacting: Customize session compaction

Event Hook

event: Listen to all OpenCode events

Events

Plugins can subscribe to events using the event hook. Here is a list of the different events available.

Command Events

  • command.executed

File Events

  • file.edited
  • file.watcher.updated

Installation Events

  • installation.updated

LSP Events

  • lsp.client.diagnostics
  • lsp.updated

Message Events

  • message.part.removed
  • message.part.updated
  • message.removed
  • message.updated

Permission Events

  • permission.asked
  • permission.replied

Server Events

  • server.connected

Session Events

  • session.created
  • session.compacted
  • session.deleted
  • session.diff
  • session.error
  • session.idle
  • session.status
  • session.updated

Todo Events

  • todo.updated

Shell Events

  • shell.env

Tool Events

  • tool.execute.after
  • tool.execute.before

TUI Events

  • tui.prompt.append
  • tui.command.execute
  • tui.toast.show

Examples

Here are some examples of plugins you can use to extend opencode.

Send notifications

Send notifications when certain events occur:
.opencode/plugins/notification.js
We are using osascript to run AppleScript on macOS. Here we are using it to send notifications.
If you’re using the OpenCode desktop app, it can send system notifications automatically when a response is ready or when a session errors.

.env protection

Prevent opencode from reading .env files:
.opencode/plugins/env-protection.js

Inject environment variables

Inject environment variables into all shell execution (AI tools and user terminals):
.opencode/plugins/inject-env.js

Custom tools

Plugins can also add custom tools to opencode:
.opencode/plugins/custom-tools.ts
The tool helper creates a custom tool that opencode can call. It takes a Zod schema function and returns a tool definition with:
  • description: What the tool does
  • args: Zod schema for the tool’s arguments
  • execute: Function that runs when the tool is called
Your custom tools will be available to opencode alongside built-in tools.

Logging

Use client.app.log() instead of console.log for structured logging:
.opencode/plugins/my-plugin.ts
Levels: debug, info, warn, error. See SDK documentation for details.

Compaction hooks

Customize the context included when a session is compacted:
.opencode/plugins/compaction.ts
The experimental.session.compacting hook fires before the LLM generates a continuation summary. Use it to inject domain-specific context that the default compaction prompt would miss. You can also replace the compaction prompt entirely by setting output.prompt:
.opencode/plugins/custom-compaction.ts
When output.prompt is set, it completely replaces the default compaction prompt. The output.context array is ignored in this case.