Custom Commands
Use Ctrl+P to open the command palette, then type a command name or description to invoke it.
Defining Commands
Commands are defined in opencode.json under the command key.
{
"command": {
"test": {
"template": "Run the full test suite with coverage report and show any failures.",
"description": "Run tests with coverage",
"agent": "build",
"model": "anthropic/claude-haiku-4-5"
}
}
}
Command Fields
| Field | Required | Description |
|---|---|---|
template | Yes | The prompt template sent to the LLM |
description | No | Short description shown in the command palette |
agent | No | Agent to use for this command (overrides current agent) |
model | No | Model to use for this command (overrides current model) |
Command Templates
The template field contains the instructions sent to the LLM when the command is invoked.
Simple Template
{
"command": {
"explain": {
"template": "Explain the selected code in detail, covering what it does, how it works, and any potential issues.",
"description": "Explain code"
}
}
}
Multi-Step Template
{
"command": {
"review": {
"template": "Review the code at $ARGUMENTS for bugs, security issues, and style problems. Provide a summary of findings with severity levels.",
"description": "Review code at path"
}
}
}
Detailed Instruction Template
{
"command": {
"document": {
"template": "Add JSDoc comments to all exported functions and classes in $ARGUMENTS. Follow the project's existing JSDoc style. Include @param and @returns tags with type information.",
"description": "Add JSDoc documentation"
}
}
}
The $ARGUMENTS Variable
$ARGUMENTS is optional — if omitted, the command runs against no specific target.
{
"command": {
"refactor": {
"template": "Refactor $ARGUMENTS to improve code quality. Extract complex logic into smaller functions, add type annotations, and improve variable naming.",
"description": "Refactor code"
},
"component": {
"template": "Create a new React component named $ARGUMENTS with TypeScript support. Include proper prop types, documentation, and a basic test file.",
"description": "Create a new component"
}
}
}
Overriding Agent and Model
Commands can specify which agent and model to use, overriding the current session settings.
Agent Override
{
"command": {
"security-audit": {
"template": "Perform a security audit of the codebase. Check for OWASP Top 10 vulnerabilities, hardcoded secrets, and insecure dependencies.",
"description": "Security audit",
"agent": "security"
}
}
}
Model Override
{
"command": {
"heavy-refactor": {
"template": "Refactor the entire module at $ARGUMENTS for better architecture.",
"description": "Major refactoring",
"model": "anthropic/claude-opus-4-5"
}
}
}
Both Override
{
"command": {
"generate-docs": {
"template": "Generate comprehensive documentation for the project at $ARGUMENTS.",
"description": "Generate documentation",
"agent": "writer",
"model": "anthropic/claude-sonnet-4-5"
}
}
}
Invoking Commands
Via Command Palette
Open the command palette with Ctrl+P and type the command name or description. Select the command from the list to invoke it.
Via Slash Command
In the input bar, type / followed by the command name:
/test
/refactor src/utils.ts
/component UserProfile
Via TUI Keybinds
Commands can be bound to keyboard shortcuts in tui.json:
{
"keybinds": {
"command_test": "ctrl+alt+t",
"command_review": "ctrl+alt+r"
}
}
Keybind IDs for commands use the format command_<name> where <name> matches the command key in the config.
Markdown Command Files
Commands can also be defined as Markdown (.md) or MDX (.mdx) files in specific directories.
File Locations
- Project-level:
.opencode/commands/(in the project root) - Global:
~/.config/opencode/commands/
Project-level files take precedence over global files.
File Format
Each file represents one command. The filename (without extension) becomes the command name.
---
description: Run tests with coverage and fail reporting
agent: build
model: anthropic/claude-haiku-4-5
---
Run the full test suite with coverage report and show any failures. Focus on:
1. Running all unit tests
2. Generating coverage report
3. Highlighting any failing tests
4. Suggesting fixes for failures
The YAML frontmatter supports the same fields as the JSON definition: description, agent, and model.
Example: Code Review Command
.opencode/commands/review.md:
---
description: Review code for bugs and style issues
agent: reviewer
---
Review the provided code for:
- Logic bugs and edge cases
- Performance issues
- Security vulnerabilities
- Style guide violations
- Missing error handling
Provide a severity rating (critical, major, minor, suggestion) for each finding.
Example: Database Migration
.opencode/commands/migrate.md:
---
description: Generate database migration
agent: builder
model: openai/gpt-5.1-codex
---
Generate a database migration for $ARGUMENTS. Include:
1. The migration SQL (both up and down)
2. A corresponding TypeScript migration file
3. Any necessary schema type updates
4. Rollback instructions
Use the existing migration patterns from the project.
Example Commands
Project Setup
{
"command": {
"setup": {
"template": "Set up the project for development. Install dependencies, create configuration files from templates, and verify the setup works.",
"description": "Initialize project setup"
}
}
}
Debug
{
"command": {
"debug": {
"template": "Debug the issue in $ARGUMENTS. Identify the root cause and suggest a fix.",
"description": "Debug an issue",
"agent": "debug",
"model": "anthropic/claude-sonnet-4-5"
}
}
}
Commit Message
{
"command": {
"commit": {
"template": "Generate a concise git commit message based on the current diff. Follow conventional commits format (type(scope): description). Consider: feat, fix, refactor, test, docs, chore.",
"description": "Generate commit message"
}
}
}
Dockerize
{
"command": {
"dockerize": {
"template": "Create a Dockerfile and docker-compose.yml for $ARGUMENTS. Use multi-stage builds, optimize layer caching, and follow security best practices.",
"description": "Dockerize a service"
}
}
}
API Client
{
"command": {
"api-client": {
"template": "Generate a type-safe API client for $ARGUMENTS. Include proper error handling, request/response types, and documentation.",
"description": "Generate API client"
}
}
}
Command Organization
For projects with many commands, group them logically:
{
"command": {
"test": { "template": "Run all tests...", "description": "Run test suite" },
"test:watch": { "template": "Run tests in watch mode...", "description": "Watch tests" },
"test:coverage": { "template": "Run tests with coverage...", "description": "Test coverage" },
"lint": { "template": "Run linter and fix issues...", "description": "Lint code" },
"lint:fix": { "template": "Auto-fix lint issues...", "description": "Auto-fix lint" },
"build": { "template": "Build the project...", "description": "Build project" },
"deploy": { "template": "Deploy to $ARGUMENTS...", "description": "Deploy to environment" }
}
}
Using colons or hyphens in command names creates logical grouping in the command palette.
Command Precedence
When commands are defined in multiple places, the resolution order is:
commandsection inopencode.json(highest priority).opencode/commands/directory files~/.config/opencode/commands/directory files (lowest priority)
Commands with the same name in a higher-priority source override lower-priority ones.
Sharing Commands
Command Palette Display
The command palette (opened with Ctrl+P) shows:
- Command name (from the key in
opencode.jsonor filename) - Description (from the
descriptionfield or frontmatter) - Agent and model overrides (if set)