Scaffold a GitHub CLI Extension with gh extension create
Half the friction of writing a gh extension is the boilerplate before your first line of logic, and gh extension create exists to skip it. This installed GitHub CLI is 2.87.3, and its wizard offers an interactive script template plus Go and other precompiled templates.
The route
Jump straight to the step you need, or tick off Done means at the end.
Before you start
Allow roughly 10 minutes for the scaffold and a first look round it. You need a shell, GitHub CLI 2.87.3 or compatible, a writable parent directory, and no root privileges. Have a short extension name ready: lowercase letters and hyphens, such as whoami. The command only creates a project locally; it does not publish a GitHub repository for you.
- Repository naming is not optional. Extension repositories start with
gh-, and the repository must provide an executable matching the extension name. - Treat every extension as untrusted code first. GitHub does not verify, sign or endorse them, so review source and provenance before installing one, including your own once it is public.
Checkpoint
Decide whether you want an interpreted script or a compiled program before you run anything. Use the script template for a portable shell program, Go when you want Go scaffolding and a compiled extension, and other when you will bring a different compiled language and build process.
1. Check the command and pick a clean parent directory
Confirm the version and the available flag before creating anything:
gh version
gh extension create --help
mkdir -p "$HOME/src/gh-extensions"
cd "$HOME/src/gh-extensions"
On the machine used for this guide, the first command reports gh version 2.87.3 (2026-02-23). The help output shows one option, --precompiled, accepting go or other. This is a plain filesystem operation, so no sudo.
Keep the parent directory separate from any existing repository while you are learning. That way it is obvious which files the scaffold created, and you will not mix starter files into an unrelated project by accident.
2. Create a script-based extension
Run this from the clean parent directory, changing the name if you like:
gh extension create whoami
Supplying a name skips the no-argument wizard and creates the project straight away. GitHub's own documentation describes this template as a Bash starter script. Follow whatever the command prints, then look round the result:
cd gh-whoami
find . -maxdepth 3 -type f -print | sort
git status --short
The exact file list is template output and can change between GitHub CLI releases, which is why find beats assuming a fixed layout. Before you try it, check the generated script is readable, understand every command inside it, and confirm the entry point is executable.
Checkpoint
A shell script is the right call, stop here. Open the entry point, replace the example behaviour, and remember that arguments typed after gh whoami are passed straight through to your script.
3. Create a Go extension instead
If you skipped the script project, return to the clean parent directory. The Go template needs an explicit flag:
cd "$HOME/src/gh-extensions"
gh extension create --precompiled=go whoami-go
cd gh-whoami-go
find . -maxdepth 3 -type f -print | sort
git status --short
The documented Go template ships Go scaffolding, a workflow, and starter code. Inspect the generated workflow before you trust it, and do not assume the project builds just because the files exist: compile and test it using what the command and the project files actually tell you.
For a precompiled extension the executable is a build output. Keep generated binaries out of version control unless the project genuinely needs otherwise, and a typical local build must leave an executable at the project root with the name the extension expects. Verify that against the generated files and current documentation before you install locally.
4. Create a non-Go precompiled extension
Choose other when you are writing in a different compiled language:
cd "$HOME/src/gh-extensions"
gh extension create --precompiled=other whoami-native
cd gh-whoami-native
find . -maxdepth 3 -type f -print | sort
git status --short
This template gives you the workflow scaffolding but leaves the implementation to you. GitHub's documentation says to put your build commands in script/build.sh so the extension can be built automatically. Read that file before you edit it, make the build produce the required executable, and test it locally.
Safety boundary
A build script executes commands from the project. Do not run it until you have read it and confirmed its toolchain, download sources and output paths. The normal workflow needs no elevated privileges.
5. Test locally before you publish anything
For a script extension, make the entry point executable and install the current directory as a local extension only once you have reviewed it:
chmod +x ./whoami
gh extension install .
gh extension list
gh whoami --help
The install step changes your GitHub CLI extension state, so skip it if you only wanted a scaffold. On supported systems it manages a local installation linked to the project. To undo it:
gh extension remove whoami
For a compiled project, build first and check the expected root executable exists and runs. Follow the generated project's own instructions, then install from the project directory and invoke the extension. If something fails, read the output before you start changing permissions or adding dependencies: a missing executable, a non-executable file, a wrong name, or an unavailable interpreter are the usual culprits.
6. Publish only after review
Publishing is a separate, deliberate step. Before it:
- Review the source and remove secrets and temporary build artefacts.
- Add a suitable
.gitignoreso build output does not leak into the repository. - Check the repository name uses the
gh-prefix, since users will invoke it asghfollowed by the extension name. - Plan release assets for every operating system and architecture you support, for precompiled extensions. GitHub's documentation sets platform asset naming conventions and requires an
.exesuffix for Windows assets. - Test a release artefact on each target before you announce it.
Done means
- Version and template confirmed: you know the installed
ghversion and which template you need. - Scaffold generated cleanly: a clean project directory holds the generated extension.
- Generated files inspected: you have read any build or workflow scripts before running them.
- Executable named and permissioned correctly: the entry point or compiled binary matches what
ghexpects. - Local invocation checked: it works, or a failure has a specific, understood cause.
- Removal known: you can undo the local install with
gh extension remove. - Publishing deferred: nothing goes public until source review is done.