Search GitHub Code from the Terminal with gh
You will finish with a repeatable way to search code on GitHub from a Linux terminal, narrow the result set, and export useful fields for a script. The examples use the installed GitHub CLI package, gh version 2.45.0-1ubuntu0.3+esm3, and the command's legacy code-search API.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a shell, gh, network access to GitHub, and an account or token if your GitHub setup requires authentication. This guide only performs searches and formats their output. It does not clone repositories, edit code or change GitHub data. No command here needs sudo.
1. Check the installed command
Confirm that the command in your path is the one you intend to run. This is a read-only check:
$ command -v gh
/usr/bin/gh
$ gh --version
gh version 2.45.0 (2024-01-10)
https://github.com/cli/cli/releases/tag/v2.45.0
Your package may report a different build date or release. The important check is that gh search code --help shows the subcommand and its current options:
$ gh search code --help
Usage: gh search code <query> [flags]
Checkpoint: if the command is missing, stop here and install GitHub CLI through your normal system package process. Do not copy a random binary into /usr/local/bin just to continue.
2. Run a small repository search
The first positional argument is the query. Separate words are combined as one search, while a quoted phrase keeps its words together:
$ gh search code panic --repo cli/cli --limit 3
cli/cli pkg/option/option.go
cli/cli internal/run/stub.go
cli/cli internal/safepaths/absolute.go
The exact paths and ordering can change as the repository changes. Treat this as a shape check, not a fixed data set. --repo takes an owner and repository in the form OWNER/REPO. The short form is -R.
For a phrase, quote the query so the shell passes it as one argument:
$ gh search code "error handling" --repo cli/cli --limit 10
Without quotes, the command receives two query terms. That is useful when you want both terms, but it is not the same as searching for the phrase.
3. Narrow results with filters
Use the command flags for the filters you apply repeatedly. This searches for deque in Python files:
$ gh search code deque --language=python --limit 10
These filters are available in the installed command:
--languagerestricts results by language.--filename package.jsonrestricts results by file name.--extension yamlrestricts results by extension.--owner microsoftrestricts results to an owner or organisation.--match pathsearches the file path rather than its contents. The other accepted value isfile.--size 10..100applies a size range in kilobytes.
For example, look for the word lint in files named package.json:
$ gh search code lint --filename package.json --limit 10
Do not add every filter by habit. A result-free search can mean that the combination is too narrow, not that the code is absent. Remove one restriction at a time and rerun the command.
4. Use GitHub query qualifiers carefully
The query can also contain GitHub search syntax, such as path:pkg or language:go:
$ gh search code panic path:pkg language:go --limit 10
Use either query qualifiers or the matching command flags when that makes the command clearer. The flags are easier to audit in a script; qualifiers are convenient for a one-off search. Check the GitHub code-search documentation when you need syntax beyond these examples.
A leading hyphen is a shell and CLI parsing trap. To search for a query that excludes a qualifier, put the complete query after --:
$ gh search code -- "panic -language:javascript"
The -- tells the command that following text is query data rather than another option. This matters when the query contains a qualifier beginning with -. Keep untrusted search text quoted, and do not construct a command with eval.
5. Inspect stable fields as JSON
The default display is designed for a terminal. For a script or a reviewable record, request explicit JSON fields instead:
$ gh search code panic --repo cli/cli --limit 3 \
--json path,repository,url
[{"path":"pkg/option/option.go","repository":{"id":"...","isFork":false,"isPrivate":false,"nameWithOwner":"cli/cli","url":"https://github.com/cli/cli"},"url":"https://github.com/cli/cli/blob/.../pkg/option/option.go"}]
The command documents path, repository, sha, textMatches and url as JSON fields. Git object IDs and result counts vary, so do not compare the complete output as if it were a permanent fixture.
Use --jq to project the fields you need. This prints repository and path as tab-separated values:
$ gh search code panic --repo cli/cli --limit 3 \
--json path,repository \
--jq '.[] | [.repository.nameWithOwner, .path] | @tsv'
cli/cli pkg/option/option.go
cli/cli internal/run/stub.go
cli/cli internal/safepaths/absolute.go
For a larger pipeline, check the exit status and preserve the raw JSON before transforming it. A successful command means the request completed; it does not mean that the search found the code you expected.
6. Handle access and legacy-search surprises
If gh reports an authentication or API error, inspect the account configuration with gh auth status. Follow your organisation's approved login process. Do not paste a token into a shell command, a ticket or a script, and do not use sudo to solve an account problem.
Code-search results are powered by what the command's manual calls a legacy GitHub code-search engine. They may differ from the results shown on github.com, and regular-expression search is not available through this API. A missing result is therefore a reason to check the query, repository visibility and web search, not proof that a string cannot exist.
Search limits are another common distraction. The default maximum is 30 code results. Set --limit deliberately when you need fewer or more results, but keep a practical limit for interactive work. If you need to process all returned records, use JSON and handle pagination or API limits in the workflow that consumes the output rather than assuming one terminal screen is complete.
Done means
gh search code QUERYreturns a result set or a clear no-results outcome.- You can restrict a search by repository, owner, language, file name, extension, path or size.
- Queries containing phrases or leading hyphens are quoted and separated from flags safely.
- JSON output names only the fields your script needs, with
--jqapplied after retrieval. - You know the local default limit is 30 and that this API uses legacy code-search behaviour.
- No repository, account setting or local file was changed by the workflow.