Home / Alt manpages / gh-extension-install(1)

  • gh-extension-install(1)
  • User command
  • linux

Install and Pin a GitHub CLI Extension Safely

Extensions run as your user with your GitHub access, so gh extension install is a trust decision wearing a one-line command. This guide covers installing from a repository, confirming gh can see it, and pinning a repeatable version. The examples use GitHub CLI 2.87.3, installed on this machine on 23 September 2026. Allow about ten minutes, longer if the repository has to build a local executable. The normal commands are unprivileged: do not reach for sudo just to install a user-level extension.

1. Check the installed command

Confirm which gh binary will run and read its help. This is read-only and does not contact a repository:

$ command -v gh
/usr/bin/gh
$ gh --version
gh version 2.87.3 (2026-02-23)
$ gh extension install --help

Two options matter here: --pin selects a release tag or commit ref, and --force forces an upgrade or overrides the case where the latest version is already installed.

Checkpoint

If gh is missing, stop and install GitHub CLI through your normal distribution or vendor process. This guide does not need a package-manager command, and adding one risks changing the wrong system.

2. Install a remote extension

For a repository hosted on GitHub, use its owner and name:

$ gh extension install OWNER/REPOSITORY

Replace both placeholders with the exact repository you have reviewed. A repository called gh-foobar gives you a command called gh foobar. Do not infer trust from the gh- prefix: an extension is executable code and can reach anything available to the account running it.

GitHub CLI first looks for release artefacts as a binary extension. Failing that, it clones the repository as a script extension and expects an executable or script in the repository root. Read the project's release notes and installation instructions before accepting either path.

A successful command returns status 0 and normally prints an installation message, but the exact output varies by extension and release. Verify the local registry afterwards:

$ gh extension list
NAME       VERSION  REPOSITORY
foobar     v1.2.3   OWNER/REPOSITORY

That table is illustrative: the version, repository and spacing come from your own installed extension. If the command fails, run gh extension list and check the spelling, authentication and network access before retrying.

3. Pin a version when repeatability matters

Without --pin, you get whatever the extension's release or repository currently calls latest. Pin a release tag instead:

$ gh extension install OWNER/REPOSITORY --pin v1.2.3
$ gh extension list

The pin is a tag or commit ref, not a version range. Script extensions document a commit ref as the useful form; binary extensions use the project's release tag. Check the repository's own release page so the ref matches the extension type and its published artefacts.

Tip

Pinning stops surprise upgrades, but it does not make an untrusted extension safe. Review the source, release provenance and permissions regardless, and if you are installing into a build or deployment account, record the ref beside the rest of that environment's inputs.

4. Install from a full repository URL

The short OWNER/REPOSITORY form only works for GitHub-hosted repositories. Use a full URL for another Git host or a GitHub Enterprise instance:

$ gh extension install https://git.example.com/OWNER/REPOSITORY

Use a URL you have checked yourself, not one copied from an untrusted shell command or issue comment. If the host needs credentials, authenticate with whatever mechanism is already approved for it.

Warning

Do not put access tokens in the URL. They can leak through shell history, process listings or logs.

5. Install a local checkout while developing

Change into the root of the local extension repository and pass a dot as the argument:

$ cd /path/to/gh-foobar
$ gh extension install .
$ gh extension list

For a local install, GitHub CLI manages the extension as a symbolic link (or an equivalent on Windows) to an executable named after the repository, sitting in the repository root. For gh-foobar, that means an executable called gh-foobar at the root; a precompiled extension has to be built and copied there manually before it will run.

Checkpoint

Confirm the file exists before you invoke the extension:

$ test -x ./gh-foobar && echo 'extension executable is ready'
extension executable is ready
$ gh foobar --help

A local link follows the checkout as it changes, which is handy for development but means the command changes whenever the working tree does. Do not treat an unreviewed working tree as a production dependency.

6. Upgrade or remove an extension deliberately

Warning

--force changes the installed extension state. Use it only once you have chosen the repository and version, and record the current one first:

$ gh extension list
$ gh extension install OWNER/REPOSITORY --pin v1.3.0 --force
$ gh extension list

This replaces or updates the existing installation; it is not a dry run. If the new version turns out unsuitable, reinstall the previously recorded tag:

$ gh extension install OWNER/REPOSITORY --pin v1.2.3 --force

Recovery

That assumes the older tag and its release artefact still exist. Before upgrading an extension used by scripts, test the new command in a separate account or checkout and keep the old ref to hand. The install command itself gives you no rollback snapshot.

Common failure checks

  • Installs but will not run: the repository may be missing the expected root executable, have the wrong executable name, or need a build step. Check the repository's documented layout rather than renaming files blindly.
  • Remote install fails outright: the release may have no compatible artefact, and the repository may not be a valid script extension either.
  • Listed but command not found: check the extension name and invoke its help with gh EXTENSION --help.
  • Entry is stale or unwanted: use the separate extension-management command shown by gh extension --help. Do not delete files from GitHub CLI's data directory by hand, or you can leave its registry inconsistent.

Done means

  • Version and help checked: gh --version and gh extension install --help confirmed the installed behaviour.
  • Repository reviewed first: the URL or OWNER/REPOSITORY value was checked before any code was installed.
  • Presence confirmed: gh extension list shows the expected extension and recorded version.
  • Pinned where it matters: a release tag or commit ref is fixed when repeatable behaviour is needed.
  • Local executable correct: a local extension has the correctly named executable in its repository root.
  • Forced upgrades reversible: any forced upgrade has a recorded previous ref you can reinstall.