

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Plugins
incomplete
2: Loading Plugins
incomplete
3: Install Plugins
incomplete
4: Plugin Transforms
incomplete
5: Plugin Hooks
incomplete
6: Plugin Tools
incomplete
7: Publishing Plugins
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
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:
For example, maybe you want to:
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.
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.