Skip to content

Instantly share code, notes, and snippets.

@zeke
Created January 13, 2026 18:10
Show Gist options
  • Select an option

  • Save zeke/1e0ba44eaddb16afa6edc91fec778935 to your computer and use it in GitHub Desktop.

Select an option

Save zeke/1e0ba44eaddb16afa6edc91fec778935 to your computer and use it in GitHub Desktop.
OpenCode vs Claude Code Hooks Comparison

OpenCode Hooks: A Comparison with Claude Code

OpenCode supports a hooks feature similar to Claude Code, but with a plugin-based architecture that offers more flexibility and programmability.

Overview

Feature Claude Code OpenCode
Primary approach Config-based shell commands Plugin-based TypeScript/JS
Hook execution Bash scripts via JSON config Full SDK access in plugins
Config hooks Main feature Experimental feature

OpenCode's Plugin-Based Hooks

OpenCode uses a plugin architecture for hooks defined in TypeScript/JavaScript. Plugins have access to the full SDK client and context.

Available Hooks

Hook Description
event Subscribe to events (file changes, session events, etc.)
config Modify configuration
tool Define custom tools
auth Custom authentication
chat.message Intercept chat messages
chat.params Modify chat parameters
permission.ask Handle permission requests
tool.execute.before Run before tool execution
tool.execute.after Run after tool execution
experimental.chat.messages.transform Transform messages
experimental.chat.system.transform Transform system prompts
experimental.session.compacting Handle session compaction

Available Events

OpenCode provides a rich event system that plugins can subscribe to:

  • File Events: file.edited, file.watcher.updated
  • Session Events: session.created, session.compacted, session.deleted, session.idle, session.status, session.updated
  • Message Events: message.part.removed, message.part.updated, message.removed, message.updated
  • Tool Events: tool.execute.after, tool.execute.before
  • Permission Events: permission.replied, permission.updated
  • LSP Events: lsp.client.diagnostics, lsp.updated
  • Command Events: command.executed

Plugin Locations

  • Project plugins: .opencode/plugin/
  • Global plugins: ~/.config/opencode/plugin/
  • npm plugins: Configured in opencode.json via plugin array

Experimental Config-Based Hooks

OpenCode also has experimental config-based hooks in opencode.json that are more similar to Claude Code's approach:

{
  "experimental": {
    "hook": {
      "file_edited": {
        "*.ts": [
          {
            "command": ["prettier", "--write"],
            "environment": { "NODE_ENV": "development" }
          }
        ]
      },
      "session_completed": [
        {
          "command": ["notify-send", "Session completed!"]
        }
      ]
    }
  }
}

Supported Config Hooks

  • file_edited - Run commands when files matching a pattern are edited
  • session_completed - Run commands when a session completes

Example Plugin Hook

Here's an example of a plugin that protects .env files from being read:

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

export default {
  "tool.execute.before": async (input, output) => {
    if (input.call.name === "Read" && input.call.input.file_path?.includes(".env")) {
      output.abort = "Cannot read .env files for security reasons"
    }
  }
} satisfies Plugin["hooks"]

Key Differences

Claude Code Hooks

  • Configured in JSON settings files
  • Execute shell commands
  • Events: PreToolUse, PostToolUse, Stop, SubagentStop, Notification, UserPromptSubmit, PreCompact, SessionStart, SessionEnd
  • Hooks receive JSON input via stdin and return exit codes or JSON output

OpenCode Hooks

  • Plugin-based with TypeScript/JavaScript
  • Full programmatic access to SDK and context
  • More experimental hooks for transforming messages and system prompts
  • Config-based hooks are experimental and limited to file_edited and session_completed

Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment