List GitHub Projects Reliably with gh project list
Someone asks which Projects your organisation has, including the dead ones, and you would rather not click through a browser to find out. gh project list gives you a repeatable listing for your account or an organisation, with closed projects on request and JSON for other commands. Nothing gets changed along the way. The examples were checked with gh 2.45.0 from Ubuntu package gh 2.45.0-1ubuntu0.3+esm3. Allow about ten minutes if GitHub CLI is already authenticated.
The route
Jump straight to the step you need, or tick off Done means at the end.
This is a read-only command. It does not create, close, edit or delete a project, and it does not require elevated privileges. You do need a working network connection and a GitHub CLI login with permission to read Projects.
1. Check the command and authentication first
Confirm which executable your shell will run and inspect its version:
$ command -v gh
/usr/bin/gh
$ gh version
gh version 2.45.0 (2026-03-17 Ubuntu 2.45.0-1ubuntu0.3+esm3)
The path and version on your machine may differ. The option set used here is present in the installed Ubuntu build. If the command is missing, install GitHub CLI using your distribution's normal package process, then return to this step.
Check the account before trying to diagnose a project-list failure:
$ gh auth status
If GitHub reports that the token lacks the read:project scope, refresh the login as directed by gh:
$ gh auth refresh -s read:project
Warning
This changes the credentials stored by GitHub CLI, so read the confirmation and choose the account you intend to use. Do not paste a token into a shell command or into a script.
Checkpoint
Continue only when gh auth status identifies the intended GitHub account and does not report a missing Projects scope.
2. List the current user's projects
Run the command with no extra options:
$ gh project list
This lists projects for the authenticated user. The default maximum is 30 projects. If the account has more than that, the result is only the first page up to that limit, not proof that no other projects exist.
Verify the default explicitly from the local help:
$ gh project list --help | grep -- '--limit'
-L, --limit int Maximum number of projects to fetch (default 30)
The output is intended for a terminal, so its columns are convenient for reading but fragile for parsing. Use the machine-readable mode in step 4 when another command or a scheduled check needs stable structured data.
3. Target an organisation and include closed projects
Pass the organisation login to --owner. Add --closed when archived planning work matters:
$ gh project list --owner example-org --closed
Replace example-org with the exact GitHub login, not the organisation's display name. Without --closed, closed projects are not included. This option changes what is fetched; it does not close or reopen anything.
Limit a deliberately small inspection, for example while checking a new owner login:
$ gh project list --owner example-org --limit 10
Use a larger explicit value for a complete inventory when you know the account can contain more than 30 projects:
$ gh project list --owner example-org --closed --limit 100
Tip
There is no promise here that 100 is enough. Choose a limit that exceeds the number you expect, then inspect whether the returned result is complete for your purpose.
4. Request JSON for scripts
Add --format json when the output will be consumed by software. First print it without reshaping the data so you can see the fields supplied by this version of GitHub CLI:
$ gh project list --owner example-org --format json | jq .
The jq program in that example is a separate local tool. If it is unavailable, omit the pipe and save the JSON to a file for inspection. Do not guess field names from a different GitHub CLI release.
GitHub CLI also provides --jq for filtering JSON inside the command. The identity filter below is a safe way to confirm that JSON mode is active without assuming a project schema:
$ gh project list --owner example-org --format json --jq .
For a script, keep the limit and closed-project decision visible beside the command:
#!/bin/sh
set -eu
gh project list \
--owner example-org \
--closed \
--limit 100 \
--format json
set -e makes an authentication, permission or network failure stop the script. That is safer than treating an empty result as a successful inventory. If you use --jq or --template, test the exact expression against the installed command after an upgrade.
5. Open the list in a browser when terminal output is not enough
Use --web to open the projects list in the browser:
$ gh project list --owner example-org --web
This is still a listing action, but it depends on a graphical or configured browser environment. On a remote shell, prefer terminal or JSON output.
Warning
Do not combine --web with a script that expects project data on standard output.
Common failure points
- Missing scope. Refresh authentication with
gh auth refresh -s read:project, then retry. The command cannot read Projects with a token that lacks the required permission. - Wrong owner. Check the login spelling and whether the authenticated account can see that organisation's projects. A display name is not necessarily the owner login.
- Missing older work. Add
--closed. The default list excludes closed projects. - Unexpectedly short output. Remember the default limit is 30. Increase
--limitand make the chosen value part of your audit notes. - Broken parser. Do not parse the human table. Switch to
--format json, inspect the actual shape, and keep the jq or Go template expression under test.
Done means
- Right account.
gh auth statusnames the intended account and it has Projects read access. - Basic listing works.
gh project listlists the current user's open projects. - Options used deliberately.
--owner,--closedand an explicit--limitappear when the inventory requires them. - Scripts fail loudly. They use
--format jsonand stop on command errors instead of mistaking an incomplete result for an empty one.