> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/opencode-ai/opencode/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom commands

> Create powerful custom commands with named arguments to streamline your workflow and automate repetitive tasks

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:

<CardGroup cols={2}>
  <Card title="XDG Config Home" icon="folder-gear">
    `$XDG_CONFIG_HOME/opencode/commands/`

    Typically: `~/.config/opencode/commands/`

    User commands available across all projects
  </Card>

  <Card title="Home Directory" icon="house">
    `$HOME/.opencode/commands/`

    Alternative user commands location

    Useful when XDG config not set
  </Card>

  <Card title="Project Directory" icon="folder-open">
    `<PROJECT_DIR>/.opencode/commands/`

    Project-specific commands

    Sharable via version control
  </Card>
</CardGroup>

<Note>
  OpenCode creates these directories automatically if they don't exist.
</Note>

## Creating basic commands

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

<Steps>
  <Step title="Create the commands directory">
    ```bash theme={null}
    mkdir -p ~/.config/opencode/commands
    ```
  </Step>

  <Step title="Create a command file">
    Create `~/.config/opencode/commands/prime-context.md`:

    ```markdown theme={null}
    RUN git ls-files
    READ README.md

    Please analyze the project structure and provide an overview.
    ```
  </Step>

  <Step title="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
  </Step>
</Steps>

## 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

<ParamField path="$ARGUMENT_NAME" type="string">
  Named argument in format `$NAME`

  **Rules:**

  * Must start with `$` followed by a capital letter
  * Can contain uppercase letters, numbers, and underscores
  * Examples: `$ISSUE_NUMBER`, `$FILE_PATH`, `$AUTHOR_NAME`
</ParamField>

### Single argument example

Create `~/.config/opencode/commands/explain-file.md`:

```markdown theme={null}
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`:

```markdown theme={null}
# 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:

```markdown theme={null}
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.md` → `user:git:commit`
* `docker/build.md` → `user:docker:build`
* `testing/unit.md` → `user:testing:unit`

## User vs project commands

<Tabs>
  <Tab title="User 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
  </Tab>

  <Tab title="Project Commands">
    **Prefix:** `project:`

    **Location:**

    * `<PROJECT_DIR>/.opencode/commands/`

    **Best for:**

    * Project-specific workflows
    * Team-shared commands
    * Project conventions
    * Build and deployment scripts

    **Examples:**

    * API endpoint documentation
    * Project-specific testing
    * Deployment procedures

    <Tip>
      Project commands can be committed to version control, allowing team members to share workflows.
    </Tip>
  </Tab>
</Tabs>

## Real-world examples

### GitHub issue workflow

`~/.config/opencode/commands/github/issue-context.md`:

```markdown theme={null}
# 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`:

```markdown theme={null}
# 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`:

```markdown theme={null}
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`:

```markdown theme={null}
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`:

```markdown theme={null}
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:

```markdown theme={null}
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

```markdown theme={null}
# 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

```markdown theme={null}
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:

<Steps>
  <Step title="Open command palette">
    Press `Ctrl+K` anywhere in OpenCode
  </Step>

  <Step title="Browse commands">
    * User commands have `user:` prefix
    * Project commands have `project:` prefix
    * Navigate with arrow keys or `j`/`k`
  </Step>

  <Step title="Execute command">
    * Press `Enter` to select
    * If command has arguments, input dialog appears
    * Enter values for each named argument
    * Press `Enter` to submit
  </Step>
</Steps>

## 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

<CardGroup cols={2}>
  <Card title="Use descriptive names" icon="tag">
    Name arguments clearly:

    * `$ISSUE_NUMBER` not `$NUM`
    * `$FILE_PATH` not `$PATH`
    * `$AUTHOR_NAME` not `$AUTHOR`
  </Card>

  <Card title="Provide context" icon="book">
    Include helpful comments:

    ```markdown theme={null}
    # Analyze Database Performance
    # Usage: Analyzes slow queries in $DATABASE_NAME
    RUN psql $DATABASE_NAME -c "..."
    ```
  </Card>

  <Card title="Validate inputs" icon="shield-check">
    Structure prompts to handle invalid inputs:

    ```markdown theme={null}
    RUN test -f "$FILE_PATH" || echo "File not found: $FILE_PATH"
    ```
  </Card>

  <Card title="Keep commands focused" icon="bullseye">
    One command = one task

    * Break complex workflows into multiple commands
    * Chain commands together when needed
  </Card>

  <Card title="Use hierarchical organization" icon="sitemap">
    Group related commands:

    * `git/` for git operations
    * `docker/` for container tasks
    * `testing/` for test commands
  </Card>

  <Card title="Document edge cases" icon="triangle-exclamation">
    Anticipate issues:

    ```markdown theme={null}
    # Note: $BRANCH_NAME should not include 'origin/'
    RUN git checkout $BRANCH_NAME
    ```
  </Card>
</CardGroup>

## Sharing commands

### Sharing with your team

Project commands in `.opencode/commands/` can be version controlled:

```bash theme={null}
# 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:

```bash theme={null}
# 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:

```bash theme={null}
git clone https://github.com/user/opencode-commands
ln -s ~/opencode-commands ~/.config/opencode/commands/imported
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Command not appearing in palette" icon="eye-slash">
    Check:

    * File has `.md` extension
    * File is in correct directory
    * Restart OpenCode to reload commands
    * Check file permissions (should be readable)
  </Accordion>

  <Accordion title="Arguments not being prompted" icon="input-text">
    Verify:

    * Arguments use format `$NAME` (capital letters)
    * Argument name starts with a letter
    * No spaces in argument name
    * Pattern: `$[A-Z][A-Z0-9_]*`
  </Accordion>

  <Accordion title="Command executes but arguments blank" icon="square">
    Check:

    * Argument names are unique
    * Typing input correctly in dialog
    * Not canceling dialog accidentally
  </Accordion>

  <Accordion title="Wrong command scope (user vs project)" icon="location-crosshairs">
    Remember:

    * Commands in `~/.config/opencode/commands/` are `user:` scoped
    * Commands in `.opencode/commands/` are `project:` scoped
    * Prefix determines scope, not location
  </Accordion>
</AccordionGroup>

## Migration from simple commands

Upgrading existing simple commands to use named arguments:

**Before:**

```markdown theme={null}
RUN gh issue view 123
RUN git log --author="john" --grep="123"
```

**After:**

```markdown theme={null}
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

<CardGroup cols={2}>
  <Card title="Built-in commands" href="/essentials/commands" icon="wand-magic-sparkles">
    Explore built-in commands like Initialize Project and Compact Session
  </Card>

  <Card title="AI tools" href="/features/ai-tools" icon="wrench">
    Learn about tools available for use in commands
  </Card>

  <Card title="Configuration" href="/reference/configuration" icon="gear">
    Configure command directories and behavior
  </Card>

  <Card title="Examples" href="https://github.com/opencode-ai/opencode-commands" icon="code">
    Browse community command collections
  </Card>
</CardGroup>
