GitHub CLI: a standalone tool, verified releases, and a skill that goes stale
GitHub describes it as GitHub’s official command line tool. The repository metadata lists Go as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.
At a glance
- What is it?
- gh is GitHub's official command line tool, a Go program that talks to the API next to your git workflow rather than wrapping git itself. The interesting parts for an adopter are the supply chain guarantees, the version drift between the tool your CI preinstalls and the one you pinned, and the agent skill that has to be updated after every release.
- Who is it for?
- Adopt gh if your team already lives in a terminal and works against GitHub.com, Enterprise Cloud or a supported Enterprise Server release, and treat the update cadence as part of the cost: a new minor every two to three weeks, plus a skill refresh for coding agents after each one.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
gh talks to the API, it does not wrap git
The design decision that separates gh from its predecessor is stated plainly in the README. For years hub was the unofficial GitHub command line tool; gh explores what an official tool can look like with a fundamentally different design. While both bring GitHub to the terminal, hub behaves as a proxy to git, and gh is a standalone tool. The longer explanation lives in docs/gh-vs-hub.md.
What that means in practice is that your git habits are untouched. gh covers pull requests, issues and other GitHub concepts, and it sits next to where you already work with git and your code rather than in front of it. If you are migrating from hub, the git half of your muscle memory keeps working and the GitHub half changes.
The tree reflects a normal Go CLI rather than a monolith script: cmd/ for commands, internal/, pkg/, api/, git/, context/, build/ and utils/, plus acceptance/ and test/ for the two test layers, script/ for build helpers, and docs/ for everything the README links to. GoReleaser configuration and a golangci config sit at the root, next to AGENTS.md and CLAUDE.md, so the project also carries instructions for agents working on the tool itself.
The preinstalled runner version moves weekly and yours does not
Installation differs by what you want to pin. On macOS you get Homebrew or a precompiled binary from the releases page, on Linux and Unix a Debian, Raspberry Pi or Ubuntu package or an rpm for Amazon Linux, CentOS, Fedora, openSUSE, RHEL and SUSE, and on Windows WinGet or a precompiled binary. Building from source is documented in docs/install_source.md, and each platform also has community-supported packages that are not official.
Two hosting paths behave differently from a local install. In a Codespace you add the devcontainer feature yourself:
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {}
}On GitHub-hosted runners the CLI is pre-installed and updated weekly. If your workflow needs a specific version, the README says you install it yourself following the platform instructions for macOS, Linux or Windows.
That weekly update is the thing to plan around. A workflow that shells out to gh inherits a version that changes without a commit on your side, and the reproducibility you get from pinning a brew or WinGet version disappears the moment the job runs on a hosted runner. If a gh flag matters to your pipeline, pin it.
One dated warning as well: the PGP signing key rotation for Linux package repositories takes effect on September 5, 2026, and users who hit package installation or update problems around it are pointed to a public announcement in the repository issues.
Immutable releases plus provenance, verified two ways
The supply chain story is the most concrete part of the project. Starting with v2.93.0, releases are published as immutable releases, so a tag cannot be moved under you. Since version 2.50.0, gh also produces a Build Provenance Attestation, which gives a cryptographically verifiable trail back to the origin repository, the git revision and the build instructions. Those attestations are signed and rely on Sigstore for PKI.
If you already have gh, verification is one command:
$ gh at verify -R cli/cli gh_2.62.0_macOS_arm64.zipIt loads the file digest, fetches the attestation, and reports the repository, the predicate type and the workflow that produced it, so the output tells you which workflow on which branch signed the artifact you are holding.
Without gh installed, the fallback is cosign, which verifies the attestation bundle against the issuing identity:
$ cosign verify-blob-attestation --bundle cli-cli-attestation-3120304.sigstore.json \
--new-bundle-format \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
--certificate-identity="https://github.com/cli/cli/.github/workflows/deployment.yml@refs/heads/trunk" \
gh_2.62.0_macOS_arm64.zipSo a fully verified install needs either a gh you already trust or cosign plus the attestation bundle. Neither path checks that the binary does what you expect, only that it is the one this project built.
gh skill install teaches a coding agent the CLI, and it expires
There is an agent skill for driving gh from coding agents, following the open Agent Skills standard, and it is installed and updated with commands built into the tool itself:
# Install the skill (user scope recommended)
gh skill install cli/cli gh --scope user
# Update the skill after a `gh` release
gh skill update ghRead the second comment as an operational requirement rather than a suggestion. The skill is a snapshot of how to drive gh, and gh ships a new minor release roughly every two to three weeks: v2.100.0 on 2026-09-03, v2.101.0 on 2026-09-15, v2.102.0 on 2026-09-30. An agent carrying an older skill will confidently use flags and command shapes that have moved, and nothing in your repository will fail to warn you, because the agent's knowledge is a file, not a dependency lock.
The scope argument is the other decision. The command recommends user scope, which installs the skill for the account rather than for a project, so a shared repository does not pin the behaviour of everyone's agent. If you would rather review a skill in the repository, the tree has a skills/ directory for exactly that.
Either way, put gh skill update in the same place as your tool upgrades, or accept that the agent's picture of the CLI drifts.
Go 1.27, and a Makefile that shells out to script/build.go
The module is github.com/cli/cli/v2 and it asks for a recent toolchain:
module github.com/cli/cli/v2
go 1.27.0
toolchain go1.27.1Both lines matter when you build from source: the go directive sets the language and minimum version, and the toolchain line names the toolchain the maintainers use, so a machine with an older Go will try to fetch a newer one.
The build itself is delegated. Rather than running go build directly, the Makefile targets bin/gh through script/build.go, and it exports the CGO_CPPFLAGS, CGO_CFLAGS and CGO_LDFLAGS variables first so the same recipe works on every platform. The EXE variable becomes .exe when GOOS is windows, which is why the targets are written as bin/gh$(EXE) and script/build$(EXE).
The test surface has two layers, and the distinction is explicit in the targets. `go test ./...` is described as just convenience tasks around go test, while acceptance testing is a separate build-tagged run:
.PHONY: test
test:
go test ./...
# For more information, see https://github.com/cli/cli/blob/trunk/acceptance/README.md
.PHONY: acceptance
acceptance:
go test -tags acceptance ./acceptanceLint is golangci-lint run ./... . If you are forking the tool rather than installing it, those four commands are your build and test surface.
Completions ship twice for zsh because Debian's fpath differs
The completions target is the most instructive corner of the Makefile, because it encodes a distribution quirk in a comment and in a copy. It runs the built binary once per shell and writes the output into the tree:
bin/gh$(EXE) completion -s bash > ./share/bash-completion/completions/gh bin/gh$(EXE) completion -s fish > ./share/fish/vendor_completions.d/gh.fish bin/gh$(EXE) completion -s zsh > ./share/zsh/site-functions/_gh
Then it copies the zsh completion to a second directory. The reason is stated: on Debian and Ubuntu the default zsh fpath does not include /usr/share/zsh/site-functions but does include /usr/share/zsh/vendor-completions, so both paths are shipped in the deb and rpm packages.
That detail is the kind of thing you inherit rather than rediscover. If you package gh for a distribution whose zsh conventions differ again, the completion silently does not load, and nothing in the build fails. Check your fpath before assuming a packaging bug.
The Makefile also reserves the site tasks for the GitHub CLI team and its release automation, cloning github/cli.github.com, which tells you where the published manual and documentation site comes from and why docs changes are not a self-service pull request against that repository.
Supported means GitHub.com, Enterprise Cloud, and a listed GHES version
The support statement is narrow in a useful way. gh is supported for users on GitHub.com, on GitHub Enterprise Cloud, and on supported GitHub Enterprise Server versions, across macOS, Windows and Linux. Usage instructions live in the manual at cli.github.com/manual, and the project is a single static binary per platform, which is why the precompiled binary route is offered everywhere.
Two consequences follow from the wording. If your organisation runs an Enterprise Server release that has aged out of the supported list, you are outside what the project claims to support, and no amount of local testing changes that; check the release list for your version before building automation on it. And if you need a new command that only makes sense internally, there is a separate path: hubbers are pointed at an internal contributions document, and everyone else to the contributing page, which covers feedback, local builds and pull requests.
The repository is not archived and its last push was on 2026-09-29, with v2.102.0 published the following day, on the trunk branch rather than main. Anything you script against the default branch should say trunk.
Editorial conclusion
Adopt gh if your team already lives in a terminal and works against GitHub.com, Enterprise Cloud or a supported Enterprise Server release, and treat the update cadence as part of the cost: a new minor every two to three weeks, plus a skill refresh for coding agents after each one. Do not adopt it expecting a git replacement, since it is a standalone tool and does not proxy git, and do not rely on the preinstalled copy in a GitHub-hosted runner, because that version is updated weekly. Verify first by running gh at verify against a downloaded release and by checking which Enterprise Server version your organisation runs against the supported list.
Frequently asked questions
What is the CLI in GitHub CLI?
gh is GitHub's official command line tool. It brings pull requests, issues and other GitHub concepts to the terminal next to where you already work with git, and it is a standalone tool rather than a proxy to git like the older hub project.
How do I use the GitHub CLI?
Usage instructions are in the manual at cli.github.com/manual. For a coding agent, the tool ships a skill command that installs and updates the agent skill: gh skill install cli/cli gh --scope user, then gh skill update gh after a release.
How do I install the GitHub CLI on macOS, Linux and Windows?
macOS offers Homebrew or a precompiled binary, Linux and Unix offer Debian, Raspberry Pi and Ubuntu packages or rpm packages for Amazon Linux, CentOS, Fedora, openSUSE, RHEL and SUSE, and Windows offers WinGet or a precompiled binary. Building from source is covered in docs/install_source.md.
How do I verify a downloaded GitHub CLI release?
If gh is already installed, run gh at verify against the downloaded archive. Since v2.93.0 releases are immutable, and since version 2.50.0 they carry build provenance attestations signed with Sigstore, which can also be checked with cosign verify-blob-attestation and the attestation bundle.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/cli-cli)