Skip to main content

OpenCode

Open-source AI coding CLI (opencode.ai). Direct competitor to Claude Code. Plugin system built with Bun/TypeScript; substantially more extensible than Claude Code’s hook system for certain use cases — especially compaction control.

Plugin System Architecture

Plugins are JS/TS modules, loaded from:
  1. Global config (~/.config/opencode/opencode.json)
  2. Project config (opencode.json)
  3. Global plugin dir (~/.config/opencode/plugins/)
  4. Project plugin dir (.opencode/plugins/)
npm plugins auto-install at startup via Bun. Local plugins load directly. Duplicate npm packages (same name + version) are deduplicated; local and npm plugins with similar names both load.

Event Surface

Claude Code hooks cover: PreToolUse, PostToolUse, Stop, Notification. OpenCode exposes a much broader surface: Tool events: tool.execute.before, tool.execute.after Session events: session.created, session.compacted, session.deleted, session.diff, session.error, session.idle, session.status, session.updated File events: file.edited, file.watcher.updated LSP events: lsp.client.diagnostics, lsp.updated TUI events: tui.prompt.append, tui.command.execute, tui.toast.show Shell events: shell.env Permission events: permission.asked, permission.replied Todo events: todo.updated

Compaction Hooks — Key Differentiator

OpenCode exposes experimental.session.compacting, which fires before the LLM generates a continuation summary. Plugins can:
  1. Inject additional context (output.context.push(...)) — domain-specific state the default compaction prompt would miss
  2. Replace the entire compaction prompt (output.prompt = "...") — full control over what survives context compression
Claude Code has no equivalent. This is the most significant architectural difference. See Claude Code vs OpenCode Plugin Systems.

Custom Tools

Plugins can register tools that become available to the AI alongside built-in tools:
Claude Code’s equivalent is MCP server registration — a heavier setup. OpenCode makes custom tools a first-class plugin concern.

Commands — Skill Equivalent

Commands are .opencode/commands/*.md files (or global ~/.config/opencode/commands/). Each file is a Markdown template that becomes a slash command.
Features: {{argument_name}} template slots, $(command) shell injection, @path/to/file.md file injection, agent binding (force execution via a specific agent). Command → Agent binding (stronger than CC’s skill model — routes to a different model entirely):

Rules — Ambient Context

Load reusable instruction files without putting everything in AGENTS.md:
Migration: CC claude-setup/rules/*.md → OpenCode rules array in opencode.json. Same files, different loading mechanism.

Agent Model

OpenCode distinguishes three modes: Primary agents (user-selectable via Tab/switch_agent): Build (all tools, default) and Plan (read-only, file edits and bash set to ask). Subagents (invoked via @name or by primary agents via Task tool): General (full tools, for parallel multi-step work) and Explore (read-only, fast codebase search). Hidden agents (system-managed, not user-selectable): compaction, title, summary. Can still be invoked programmatically via the Task tool. Custom agents: defined in opencode.json or as markdown files in ~/.config/opencode/agents/ (global) or .opencode/agents/ (per-project). Markdown file name becomes agent name. Key options: mode (primary/subagent/all), model, temperature, steps (max iterations), permission, hidden, color.

Permission System

Per-tool permissions: allow, ask, deny. Can be set globally or per-agent, with bash command glob patterns:
Available permission keys: read, edit, glob, grep, list, bash, task, external_directory, todowrite, webfetch, websearch, lsp, skill, question, doom_loop.

{file:./path} Prompt Injection

Agent prompts can reference external files:
Path is relative to the config file location — works for both global and project-level configs.

AGENTS.md Support

OpenCode reads AGENTS.md natively with the following precedence (per directory):
Global: ~/.config/opencode/AGENTS.md > ~/.claude/CLAUDE.md Claude Code compatibility can be disabled:

Multi-file Instructions via opencode.json

The instructions field escapes the single-file limitation — accepts glob patterns and remote URLs:
All instruction files are combined with AGENTS.md. Remote instructions fetched with 5-second timeout.

Config Precedence

8-level merge order (low → high): remote org defaults → global (~/.config/opencode/opencode.json) → OPENCODE_CONFIG env → project (opencode.json) → .opencode/ dirs → OPENCODE_CONFIG_CONTENT env → managed files → MDM .mobileconfig (highest, not user-overridable). Config files are merged not replaced — conflicting keys override, non-conflicting keys from all sources are preserved. Variable substitution in config values:
  • {env:VAR} — substitutes environment variable
  • {file:path} — substitutes file contents (for keeping API keys out of config)
TUI settings live in a separate tui.json file — not in opencode.json. Managed settings (enterprise): deploy .mobileconfig via MDM (Jamf, Kandji, FleetDM) using ai.opencode.managed PayloadType for settings users cannot override. opencode debug config shows resolved config including managed preferences. Inline agent definition in config:

Community Model-Routing Patterns

From r/opencodeCLI community (2026-05-03, n≈30 responses): Key insight (settings-opencode author): “You need a good harness. Use specialized agents, skills, hooks — anything that helps you have the outcome you desire.” Model capability < workflow structure. DeepSeek reasoning effort: set max reasoning via ctrl+t or config when using direct API. Resellers (OpenRouter) may not support reasoning effort — use direct API. Opus as orchestrator pattern: Opus generates a bash script that dispatches other models, deciding which model fits each task + capping expensive model quotas. Moves model routing from static config to dynamic agent decision. Auto-learned skill accumulation: running CC + OpenCode simultaneously with session-learning hooks creates duplicate skills (e.g., three versions of the same skill name). Periodic triage required. See Instinct Clustering (Homunculus Pattern).

Headless & Programmatic Mode

opencode run — Subprocess / Non-interactive

The pi -p equivalent. Runs a single prompt and exits:
Key flags: --model, --agent, --attach, --continue, --session, --fork, --file, --format json, --variant, --dangerously-skip-permissions.

opencode serve — Persistent HTTP Server

Every opencode (TUI) run starts an embedded HTTP server; TUI is just a client. opencode serve exposes the same server standalone without TUI. Full OpenAPI 3.1 spec at http://<host>:<port>/doc. Warm-server pattern (avoids MCP cold-boot on every invocation):

Key HTTP Endpoints

ACP Protocol

opencode acp = stdin/stdout nd-JSON server for IDE embedding (no HTTP overhead).

Experimental Orchestration Flags

  • OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS — background subagent tasks
  • OPENCODE_EXPERIMENTAL_SCOUT — Scout subagent (read-only fast search)
  • OPENCODE_EXPERIMENTAL_PLAN_MODE — plan mode
See Opencode Headless Api for full API reference and orchestration patterns.

Relation to Existing Wiki