We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Plugins

Plugins extend OpenCode itself. They run code inside the agent harness, kinda like editor extensions for VS Code or Neovim.

Plugins can do things like:

  • Hook into tool execution
  • Modify model context before a model call
  • Add support for a new authentication flow
  • Register new agents, commands, skills, or tools

For example, maybe you want to:

  • Save all TODOs generated by the agent to a GitHub issue tracker
  • Keep a local audit log of tool calls
  • Force a custom "initialize" script to run before each new session is started

For personal use, I just make my OpenCode's default experience match what I want, so I don't need plugins. That said, if you're trying to share a specific experience across a team or publicly, they can make a lot of sense.

How Plugins Work

Each OpenCode plugin has a unique id and (typically) a setup function. Export the result of Plugin.define as the module's default export:

import { Plugin } from "@opencode/plugin";

export default Plugin.define({
  id: "bootdev.example",
  setup: async (ctx) => {
    // Register transforms, hooks, or tools here
  },
});

For example, this plugin keeps a local audit log so you can inspect which tools the agent used and whether they succeeded:

import { appendFile } from "node:fs/promises";
import { join } from "node:path";
import { Plugin } from "@opencode/plugin";

export default Plugin.define({
  id: "bootdev.audit-log",
  setup: async (ctx) => {
    const logPath = join(ctx.location.directory, "audit.jsonl");

    await ctx.tool.hook("execute.after", async (event) => {
      const entry = {
        timestamp: new Date().toISOString(),
        sessionID: event.sessionID,
        tool: event.tool,
        status: event.status,
      };

      try {
        await appendFile(logPath, JSON.stringify(entry) + "\n");
      } catch (error) {
        console.error("could not write audit log:", error);
      }
    });
  },
});

execute.after is a hook that runs the provided code after any tool call succeeds or fails. We'll get into hooks a bit later.