Skip to main content
Custom commands allow you to create reusable, parameterized prompts stored as Markdown files. They support named arguments for dynamic content, making them perfect for workflow automation and repetitive tasks.

Overview

Custom commands are predefined prompts stored as .md files that can be executed from OpenCode’s command palette (Ctrl+K). They support:
  • Named arguments with clear, semantic variable names
  • Multiple argument types per command
  • Organized hierarchies using subdirectories
  • Two scopes: user-level and project-level commands

Command locations

OpenCode loads custom commands from three locations:

XDG Config Home

$XDG_CONFIG_HOME/opencode/commands/Typically: ~/.config/opencode/commands/User commands available across all projects

Home Directory

$HOME/.opencode/commands/Alternative user commands locationUseful when XDG config not set

Project Directory

<PROJECT_DIR>/.opencode/commands/Project-specific commandsSharable via version control
OpenCode creates these directories automatically if they don’t exist.

Creating basic commands

The simplest form is a Markdown file containing the prompt text:
1

Create the commands directory

mkdir -p ~/.config/opencode/commands
2

Create a command file

Create ~/.config/opencode/commands/prime-context.md:
RUN git ls-files
READ README.md

Please analyze the project structure and provide an overview.
3

Use the command

  1. Press Ctrl+K to open command palette
  2. Select user:prime-context
  3. The command content is sent to the AI

Named arguments

Named arguments make commands dynamic and reusable. They follow the pattern $NAME where NAME consists of uppercase letters, numbers, and underscores, and must start with a letter.

Argument syntax

$ARGUMENT_NAME
string
Named argument in format $NAMERules:
  • Must start with $ followed by a capital letter
  • Can contain uppercase letters, numbers, and underscores
  • Examples: $ISSUE_NUMBER, $FILE_PATH, $AUTHOR_NAME

Single argument example

Create ~/.config/opencode/commands/explain-file.md:
RUN ls -la $FILE_PATH
READ $FILE_PATH

Please explain what this file does and document its main components.
When you run user:explain-file, OpenCode prompts:
Enter value for FILE_PATH:
[                    ]

Multiple arguments example

Create ~/.config/opencode/commands/fetch-issue.md:
# Fetch Context for Issue $ISSUE_NUMBER

RUN gh issue view $ISSUE_NUMBER --json title,body,comments
RUN git log --author="$AUTHOR_NAME" --grep="$ISSUE_NUMBER" -n 10

Analyze the issue and related commits.
When executed, OpenCode prompts for each unique argument:
  1. ISSUE_NUMBER
  2. AUTHOR_NAME

Argument reuse

Arguments can be used multiple times throughout the command:
RUN grep -r "$PATTERN" $DIRECTORY
RUN find $DIRECTORY -type f -name "*$PATTERN*"

Search for "$PATTERN" in directory "$DIRECTORY" and analyze results.
OpenCode recognizes that $PATTERN and $DIRECTORY each appear twice, but only prompts for them once.

Organizing commands

Use subdirectories to organize related commands:
~/.config/opencode/commands/
├── git/
│   ├── commit.md
│   ├── pr.md
│   └── branch.md
├── docker/
│   ├── build.md
│   └── deploy.md
└── testing/
    ├── unit.md
    └── integration.md
Subdirectories become part of the command ID:
  • git/commit.mduser:git:commit
  • docker/build.mduser:docker:build
  • testing/unit.mduser:testing:unit

User vs project commands

Prefix: user:Locations:
  • $XDG_CONFIG_HOME/opencode/commands/
  • $HOME/.opencode/commands/
Best for:
  • Personal workflows
  • General-purpose commands
  • Commands used across multiple projects
  • Development environment setup
Examples:
  • Code review templates
  • Personal productivity commands
  • Common debugging workflows

Real-world examples

GitHub issue workflow

~/.config/opencode/commands/github/issue-context.md:
# Gather Context for Issue #$ISSUE_NUMBER

RUN gh issue view $ISSUE_NUMBER --json title,body,comments,labels
RUN gh issue list --search "$ISSUE_NUMBER" --json number,title,state
RUN git log --all --grep="$ISSUE_NUMBER" --oneline -n 20

Please analyze this issue and provide:
1. Summary of the issue
2. Related changes in git history
3. Suggested approach for resolution

Code review preparation

~/.config/opencode/commands/git/review-prep.md:
# Review Changes for $BRANCH_NAME

RUN git checkout $BRANCH_NAME
RUN git diff main...$BRANCH_NAME
RUN git log main...$BRANCH_NAME --oneline

Please review these changes and:
1. Identify potential issues
2. Suggest improvements
3. Check for missing tests

API endpoint documentation

.opencode/commands/api/document-endpoint.md:
RUN grep -r "$ENDPOINT_PATH" src/
RUN find . -name "*$CONTROLLER_NAME*" -type f

Document the API endpoint at $ENDPOINT_PATH:
1. Request/response formats
2. Authentication requirements
3. Example usage
4. Error handling

Database migration

.opencode/commands/db/create-migration.md:
RUN ls -la db/migrations/
RUN cat db/schema.sql

Create a database migration for: $MIGRATION_DESCRIPTION

Requirements:
1. Up migration
2. Down migration
3. Follow project naming convention
4. Include proper indexing

Test generation

~/.config/opencode/commands/testing/generate-tests.md:
READ $FILE_PATH
RUN find . -name "*test*" -path "*$(dirname $FILE_PATH)*" -type f

Generate comprehensive tests for $FILE_PATH:
1. Unit tests for all functions
2. Edge cases
3. Error handling
4. Mock external dependencies

Advanced patterns

Conditional logic in commands

While commands don’t have built-in conditionals, you can structure prompts to guide the AI:
RUN test -f $CONFIG_FILE && cat $CONFIG_FILE || echo "Config not found"
RUN git branch --show-current

Analyze $CONFIG_FILE and:
- If config exists, validate settings
- If config missing, suggest default configuration
- Consider the current git branch context

Multi-step workflows

# Step 1: Gather Context
RUN git status
RUN git diff

# Step 2: Analyze Changes
RUN git log -n 5 --oneline

# Step 3: Run Tests
RUN npm test -- $TEST_PATTERN

Based on the test results for "$TEST_PATTERN":
1. Identify failing tests
2. Suggest fixes
3. Recommend additional test coverage

Environment-aware commands

RUN echo "Environment: $ENVIRONMENT"
RUN cat .env.$ENVIRONMENT

Prepare deployment to $ENVIRONMENT:
1. Validate environment configuration
2. Check required secrets are set
3. Verify database migrations
4. Generate deployment checklist

Command palette integration

Accessing custom commands:
1

Open command palette

Press Ctrl+K anywhere in OpenCode
2

Browse commands

  • User commands have user: prefix
  • Project commands have project: prefix
  • Navigate with arrow keys or j/k
3

Execute command

  • Press Enter to select
  • If command has arguments, input dialog appears
  • Enter values for each named argument
  • Press Enter to submit

Argument input dialog

When a command with named arguments is executed:
  1. Multi-argument dialog appears
  2. Arguments shown in order of first appearance
  3. Each argument has its own input field
  4. Use Tab to move between fields
  5. Press Enter to submit all values
  6. Press Escape to cancel
Dialog example:
┌─ Command Arguments ────────────────┐
│ Enter values for user:git:pr       │
│                                    │
│ BRANCH_NAME:                       │
│ [feature/new-api______________]    │
│                                    │
│ BASE_BRANCH:                       │
│ [main_________________________]    │
│                                    │
│ [Submit] [Cancel]                  │
└────────────────────────────────────┘

Best practices

Use descriptive names

Name arguments clearly:
  • $ISSUE_NUMBER not $NUM
  • $FILE_PATH not $PATH
  • $AUTHOR_NAME not $AUTHOR

Provide context

Include helpful comments:
# Analyze Database Performance
# Usage: Analyzes slow queries in $DATABASE_NAME
RUN psql $DATABASE_NAME -c "..."

Validate inputs

Structure prompts to handle invalid inputs:
RUN test -f "$FILE_PATH" || echo "File not found: $FILE_PATH"

Keep commands focused

One command = one task
  • Break complex workflows into multiple commands
  • Chain commands together when needed

Use hierarchical organization

Group related commands:
  • git/ for git operations
  • docker/ for container tasks
  • testing/ for test commands

Document edge cases

Anticipate issues:
# Note: $BRANCH_NAME should not include 'origin/'
RUN git checkout $BRANCH_NAME

Sharing commands

Sharing with your team

Project commands in .opencode/commands/ can be version controlled:
# Add to git
git add .opencode/commands/
git commit -m "Add custom OpenCode commands"

# Team members get them automatically
git pull

Sharing user commands

Create a dotfiles repository:
# In your dotfiles repo
mkdir -p config/opencode/commands
cp -r ~/.config/opencode/commands/* config/opencode/commands/

# Others can symlink
ln -s ~/dotfiles/config/opencode ~/.config/opencode

Publishing command collections

Create a dedicated repository:
opencode-commands/
├── README.md
├── git/
│   ├── pr.md
│   └── commit.md
├── docker/
│   └── deploy.md
└── docs/
    └── examples.md
Users can clone and symlink:
git clone https://github.com/user/opencode-commands
ln -s ~/opencode-commands ~/.config/opencode/commands/imported

Troubleshooting

Check:
  • File has .md extension
  • File is in correct directory
  • Restart OpenCode to reload commands
  • Check file permissions (should be readable)
Verify:
  • Arguments use format $NAME (capital letters)
  • Argument name starts with a letter
  • No spaces in argument name
  • Pattern: $[A-Z][A-Z0-9_]*
Check:
  • Argument names are unique
  • Typing input correctly in dialog
  • Not canceling dialog accidentally
Remember:
  • Commands in ~/.config/opencode/commands/ are user: scoped
  • Commands in .opencode/commands/ are project: scoped
  • Prefix determines scope, not location

Migration from simple commands

Upgrading existing simple commands to use named arguments: Before:
RUN gh issue view 123
RUN git log --author="john" --grep="123"
After:
RUN gh issue view $ISSUE_NUMBER
RUN git log --author="$AUTHOR" --grep="$ISSUE_NUMBER"
Benefits:
  • More flexible
  • Reusable across different issues
  • Self-documenting
  • Team-friendly

Next steps

Built-in commands

Explore built-in commands like Initialize Project and Compact Session

AI tools

Learn about tools available for use in commands

Configuration

Configure command directories and behavior

Examples

Browse community command collections

Build docs developers (and LLMs) love