GitHub CLI: Official Command-Line Tool for GitHub
What GitHub CLI is
GitHub CLI, usually invoked as gh, is GitHub's official command-line tool. Its README describes it as "GitHub on the command line": it brings pull requests, issues and other GitHub concepts into the terminal, next to where you are already running git and editing code. The manual calls it a command-line interface to GitHub "for use in your terminal or your scripts", and both halves of that matter. Interactively, gh replaces a lot of tab-switching to the browser. In scripts and CI, it is an authenticated client for the GitHub REST and GraphQL APIs with structured JSON output.
The project is written in Go, licensed under MIT and developed in the open at cli/cli by a team at GitHub. The README states support for GitHub.com, GitHub Enterprise Cloud and supported GitHub Enterprise Server versions, on macOS, Windows and Linux. The audience is anyone who works with GitHub repositories day to day: developers opening and reviewing pull requests, maintainers triaging issues and cutting releases, platform engineers scripting organisation-wide changes, and CI authors who want a reliable way to call the GitHub API from a workflow step.
How it works
A standalone Go binary built on Cobra
Unlike its predecessor hub, which wrapped and proxied git, gh is a standalone executable. The project-layout document walks through a single invocation. The main package in cmd/gh/main.go builds a root command with root.NewCmdRoot() and dispatches to it. The root command knows every nested command, and arguments such as issue list --limit 5 route execution to the RunE block of the matching cobra.Command, in this case pkg/cmd/issue/list/list.go. Flags are parsed into an options struct, a run function gathers data from the GitHub API and the local git repository, and output goes to standard output and standard error through an I/O streams abstraction. Errors end the process with a non-zero exit status.
Each command lives at pkg/cmd/<command>/<subcommand>/<subcommand>.go, with its help text embedded in the source. During the release process those help topics are converted automatically into the manual pages published at cli.github.com/manual, so the manual and gh help are generated from the same text.
Repository and host context
Most commands infer which repository and host to talk to from the git remotes of the current directory. You can override that with -R or the GH_REPO environment variable (in [HOST/]OWNER/REPO format), and pick a host with GH_HOST. The help topic on environment variables spells out the host model: github.com, subdomains of ghe.com and github.localhost use GH_TOKEN or GITHUB_TOKEN, and any other host is treated as GitHub Enterprise Server and uses GH_ENTERPRISE_TOKEN or GITHUB_ENTERPRISE_TOKEN. The developer guide on API and hosts adds that the codebase uses feature detection for APIs that are not yet available on every supported server, including GHES, rather than assuming GitHub.com behaviour everywhere.
Authentication and credentials
gh auth login defaults to a web-based browser flow. According to its help text, the resulting token is stored in the system credential store, and if no credential store is found or it cannot be used, gh falls back to writing the token to a plain-text file; gh auth status shows where it ended up. You can also pipe a classic personal access token in with --with-token (minimum scopes repo, read:org and gist), or rely on environment variables for headless use. Choosing SSH as the git protocol makes gh look for existing SSH keys and offer to create and upload one. Since v2.40.0, logins are additive, so several accounts can be logged in to one host and swapped with gh auth switch.
Key features
- Pull requests from the terminal.
gh pr createcan push the current branch, offer to fork, autofill title and body from commits with--fill, request reviewers, add the PR to projects and attach up to 50 images or videos per command;gh pr checkoutfetches a PR locally, optionally into a new worktree. - Broad command surface. The manual lists top-level groups including
issue,pr,repo,release,run,workflow,secret,variable,cache,ruleset,project,gist,codespace,search,discussion,attestation,org,label,ssh-key,gpg-key,statusandbrowse. - Raw API access.
gh apimakes authenticated REST (v3) or GraphQL (v4) requests, fills{owner},{repo}and{branch}placeholders from the current repository, converts typed fields, reads bodies from files or stdin, and paginates with--paginate, optionally merging pages with--slurp. - JSON output with built-in jq and Go templates. Many commands accept
--jsonwith a field list, then--jqor--templateto shape the result. The formatting help topic notes that thejqutility does not need to be installed for--jqto work, and adds template helpers such astablerow,timeagoandhyperlink. - Aliases.
gh alias setdefines shortcuts that expand to full commands with positional placeholders, or to shell expressions run throughshwhen the expansion starts with!or--shellis given. - Extensions. Any repository named
gh-<name>that ships an executable of the same name can be installed as a newghsubcommand, as a precompiled binary from releases or as a script cloned from the repository;gh extension createscaffolds one, including a Go template. - Multiple accounts. Additive
auth login,auth switch, and a--userflag onauth token,auth switchandauth logoutfor non-interactive disambiguation. - Git credential integration. When configured as a git credential helper, the active account's token is used for git operations as well as API requests.
- Scriptable behaviour. Documented exit codes (0 success, 1 failure, 2 cancelled, 4 authentication required),
GH_PROMPT_DISABLEDto turn off prompts,GH_FORCE_TTYfor terminal-style output when piped, andGH_DEBUG=apito log HTTP traffic. - Verifiable releases. Since 2.50.0 releases carry Sigstore-signed build provenance attestations, and from v2.93.0 they are published as immutable releases.
Getting started
Install
The officially supported channels are Homebrew on macOS and Linux, WinGet on Windows, the project's own Debian and RPM repositories, and precompiled binaries on the releases page. On macOS or Linux with Homebrew:
brew install ghOn Windows:
winget install --id GitHub.cli --source wingetThe Windows doc warns that the installer modifies PATH, and in Windows Terminal you need a new window, not just a new tab, for that to take effect. On Fedora or RHEL-family systems using DNF5, the Linux install doc adds the project's repository first:
sudo dnf install dnf5-plugins
sudo dnf config-manager addrepo --from-repofile=https://cli.github.com/packages/rpm/gh-cli.repo
sudo dnf install ghDebian and Ubuntu use a longer snippet in the same doc that installs the signed keyring under /etc/apt/keyrings and adds cli.github.com/packages as an apt source. Building from source requires Go 1.26 or newer; on Unix-like systems make install installs to /usr/local by default, and on Windows go run script\build.go produces bin\gh.exe with no install step. In GitHub Codespaces, the README adds gh through the ghcr.io/devcontainers/features/github-cli:1 dev container feature, and GitHub-hosted Actions runners ship with it pre-installed and updated weekly.
Authenticate and try a few commands
Start the interactive login, or read a token from a file for headless setups:
gh auth login
gh auth login --with-token < mytoken.txtFrom inside a clone, open a pull request for the current branch and check out someone else's:
gh pr create --title "The bug is fixed" --body "Everything works again"
gh pr checkout 32Ask for JSON and filter it without installing jq:
gh pr list --json number,title,author
gh pr list --json author --jq '.[].author.login'Call any API endpoint, with the owner and repo filled in from the current directory:
gh api repos/{owner}/{repo}/releasesDefine an alias and install an extension:
gh alias set bugs 'issue list --label=bugs'
gh extension install owner/gh-extensionFor coding agents, the README documents a built-in command that installs the project's agent skill:
gh skill install cli/cli gh --scope userIf you download a release binary manually and already have gh, the README shows verifying its attestation with gh at verify -R cli/cli followed by the archive name; cosign verify-blob-attestation is the documented alternative when gh is not installed yet.
Use cases
- Pull request workflow without the browser. Create a PR from the branch you just pushed, request reviewers and team reviewers, check out a colleague's PR into a separate worktree to test it, and come back to the web UI only when you want to.
- GitHub Actions and CI scripts. The login help says to add
GH_TOKEN: ${{ github.token }}to a step'senv, which makesghavailable for commenting on PRs, creating releases, downloading run artifacts or querying the API from a workflow, with documented exit codes for control flow. - One-off API automation.
gh apicovers endpoints that have no dedicated subcommand: updating organisation custom-property schemas, posting issue comments, paging through every repository a user owns with GraphQL, or feeding a JSON file to the rulesets API. - Reporting and triage. Combine
--jsonwith--jqor--templateto produce tables of open PRs, labelled issues or review state for a standup or a dashboard script. - Work and personal accounts on one machine. Log in to both on github.com, switch with
gh auth switch, and pull a specific account's token withgh auth token --userfor a single command. - GitHub Enterprise Server. Authenticate to an internal host with
gh auth login --hostnameand setGH_HOSTorGH_ENTERPRISE_TOKENfor scripts that target it. - Team-specific tooling. Package an internal workflow as a
gh-extension so it inherits authentication and host handling, rather than shipping another standalone CLI. The project's own guide for GitHub teams recommends starting new commands this way, as Go extensions built on thego-ghlibrary.
How it compares
gh and hub
The project names hub as the obvious comparison. For many years hub was the unofficial GitHub command-line tool. The gh-vs-hub document explains that GitHub chose to start fresh rather than adopt hub, without ten years of design decisions and without the assumption that the tool can safely be aliased to git. The key design difference, per the README, is that hub behaves as a proxy to git, while gh is a standalone tool that is more opinionated about GitHub workflows. The document says plainly that if you want a wrapper for git itself, hub is likely the better choice, that gh is not intended to be an exact replacement, and that GitHub is not shutting down or changing hub. The other distinction it draws is support: gh is maintained by a team working on behalf of GitHub, while hub is maintained by a GitHub employee in spare time.
gh, the web UI and plain git
gh does not replace git; it handles the parts of the workflow that live on GitHub rather than in your repository, such as pull requests, issues, Actions runs, releases, secrets and rulesets, and it can configure git's credential handling. Compared with the web UI, the trade-off is the usual one for CLIs: scriptability, JSON output and staying in the terminal, versus richer visual review of diffs and discussions. gh browse and the --web flags on many commands acknowledge that the two are meant to be used together. Compared with calling the REST or GraphQL APIs directly with curl, gh api handles authentication, host selection, pagination and placeholder expansion, which removes most of the boilerplate in small scripts.
Things to know before adopting
- Token storage can fall back to plain text. The login help states that tokens go to the system credential store, but if none is available or it fails,
ghwrites the token to a plain-text file. On headless servers and minimal containers, checkgh auth statusto see where the token is stored, or use environment-variable tokens instead. An--insecure-storageoption also exists. - Fine-grained tokens need care. The login help warns that passing a fine-grained personal access token to
--with-tokencan cause confusing behaviour across resources, and recommendsGH_TOKENfor fine-grained tokens. Expiring credentials are a preference that depends on the host and OAuth app configuration; with them, git 2.46 or newer is recommended so a credential cache does not reuse an expired token. - Telemetry is collected, with opt-outs. GitHub's telemetry page describes pseudonymous usage data (command name, flags, OS, architecture, CLI version, a device identifier and whether it runs in a TTY, CI or Actions). It is not collected when the target is GitHub Enterprise Server. Opt out with
GH_TELEMETRY=false,DO_NOT_TRACK=trueorgh config set telemetry disabled, or set it tologto print the payload to stderr instead of sending it. The page notes that extensions may collect their own data, which these settings do not control. - Extensions run third-party code. The extension help is explicit: extensions are not verified, signed or endorsed by GitHub, installing or upgrading one means trusting its publisher, and reviewing source and provenance is your responsibility. Use
--pinif you want a fixed tag or commit. - Update checks.
ghchecks for a new version once every 24 hours and prints a notice on stderr; extensions do the same.GH_NO_UPDATE_NOTIFIERandGH_NO_EXTENSION_UPDATE_NOTIFIERturn these off. - Enterprise host support has edges. GHES is supported for supported server versions, but some features depend on API availability, and the multiple-accounts document notes that the browser account switcher during the device OAuth flow had not reached GHES, so you must be signed in as the right user in the browser first. Some details in that document are marked as outdated.
- Packaging: prefer official channels. Community packages are explicitly unsupported by the team. The Linux doc says the Debian community
2.45.x/2.46.xpackage is broken because of deprecated GitHub APIs and recommends the official Debian repository instead. The macOS doc notes that the.pkginstaller is unsigned, with signing work tracked in an open issue. The README also flags a PGP signing-key rotation for the Linux package repositories effective September 5, 2026, which can cause install or update errors until the new key is trusted. - Terminal quirks on Windows. MinTTY, the default terminal in Git for Windows, has known prompting problems; the help topic suggests enabling pseudo-console support, using Windows Terminal, or prefixing commands with
winpty. - Immutable config managers. Since v2.40.0,
ghwrites aversionfield toconfig.yml; users managing config with tools like Nix home-manager need to addversion: 1themselves. - Contribution scope. External pull requests are accepted only for issues labelled
help wantedwith explicit acceptance criteria, and issues markedcoreare off limits. Security reports go through GitHub's HackerOne programme, and dependency CVE reports need evidence the vulnerable code is reachable, which the team checks withgovulncheck.
Project activity
As of November 2026 the cli/cli repository has about 46,900 stars and around 9,300 forks on GitHub. It was created in October 2019, the project's own announcement of a public beta followed in early 2020, and the default branch trunk received a push the day before writing. The code is Go, licensed under MIT, and building it requires Go 1.26 or newer.
The internal contribution guide describes a release roughly every other week, sometimes skipped when a week's changes are light, with no promised cadence. The releasing document describes the pipeline: Linux binaries built on Ubuntu, Windows binaries built and signed on Windows, macOS binaries built, signed and notarised on macOS, all uploaded to a GitHub Release with a changelog generated from merged pull requests, while Homebrew picks up new versions through autobump every three hours. Deployments require maintainer approval.
The source, issue tracker and releases are at github.com/cli/cli, and the manual and install packages are at cli.github.com.
Enjoying this project?
Discover more amazing open-source projects on TechLogHub. We curate the best developer tools and projects.
Repository:https://github.com/cli/cli
GitHub - cli/cli: GitHub CLI: Official Command-Line Tool for GitHub
GitHub CLI (gh) is GitHub's official MIT-licensed command-line tool in Go. It brings pull requests, issues, Actions, releases and raw REST/GraphQL API calls to ...
github - cli/cli
Related Projects
Maintain GitHub CLI: Official Command-Line Tool for GitHub? Add the badge to your README
Show that the project is featured on TechLogHub and send readers to this write-up.
[](https://techloghub.com/open-source/github-cli?utm_source=techloghub_badge&utm_medium=referral&utm_campaign=readme)
