GitHub CLI extensions are community-built or custom commands that extend gh with new functionality. They are Git repositories whose name starts with gh- and contain an executable of the same name.

How Extensions Work

  • An extension named gh-dash provides the command gh dash
  • All arguments passed to gh <extname> are forwarded to the gh-<extname> executable
  • Extensions cannot override built-in gh commands
  • Extension update checks happen once every 24 hours automatically

Discovering Extensions

Browse the Registry

gh extension browse

This opens an interactive TUI (terminal UI) for browsing available extensions.

Search for Extensions

gh extension search "dashboard"
gh extension search "label"
gh extension search --limit 30

You can also browse the registry on GitHub: github.com/topics/gh-extension

Installing Extensions

# Install from a GitHub repository
gh extension install dlvhdr/gh-dash
gh extension install vilmibm/gh-screensaver
gh extension install mislav/gh-branch
 
# Install a specific version
gh extension install dlvhdr/gh-dash --pin v1.0.0

Listing Installed Extensions

gh extension list

Upgrading Extensions

# Upgrade a specific extension
gh extension upgrade dlvhdr/gh-dash
 
# Upgrade all installed extensions
gh extension upgrade --all

Removing Extensions

gh extension remove dlvhdr/gh-dash

Executing an Extension Directly

If an extension name conflicts with a built-in command or you want to invoke it explicitly, use exec:

gh extension exec <extname> [args...]

This is useful when an extension has the same name as a core gh command — gh extension exec bypasses the built-in command and runs the extension directly.

Creating Your Own Extension

Scaffold a New Extension

# Create a basic shell script extension
gh extension create my-extension
 
# Create a Go-based extension (compiled binary)
gh extension create my-extension --precompiled=go
 
# Create an extension with other precompiled languages
gh extension create my-extension --precompiled=other

This creates a repository called gh-my-extension with the boilerplate structure.

Extension Structure

A minimal shell extension:

gh-my-extension/
├── gh-my-extension    # Executable script (Bash, Python, etc.)

A Go extension:

gh-my-extension/
├── main.go
├── go.mod
├── go.sum
└── .github/
    └── workflows/
        └── release.yml   # Auto-builds binaries for all platforms

Shell Script Example

#!/usr/bin/env bash
# gh-my-extension
set -e
 
echo "Hello from my custom gh extension!"
echo "Repository: $(gh repo view --json nameWithOwner --jq '.nameWithOwner')"
echo "Arguments: $@"

Publishing

  1. Push your extension repo to GitHub
  2. Ensure the repo name starts with gh-
  3. Add the gh-extension topic to the repo
  4. Others can install it with gh extension install yourname/gh-my-extension
ExtensionCommandDescription
gh-dashgh dashBeautiful dashboard for PRs and issues
gh-copilotgh copilotAI-powered suggestions in the terminal
gh-poigh poiClean up local branches safely
gh-branchgh branchFuzzy branch finder
gh-markdown-previewgh markdown-previewPreview markdown files locally

Disabling Update Notifications

export GH_NO_EXTENSION_UPDATE_NOTIFIER=1

Aliases

The gh extension command also responds to gh ext and gh extensions.

Exercises

  1. Search for extensions: gh extension search "dashboard"
  2. Install one: gh extension install dlvhdr/gh-dash
  3. List installed: gh extension list
  4. Try it: gh dash
  5. Create your own: gh extension create hello-world
  6. Clean up: gh extension remove dlvhdr/gh-dash