CLI tool
abhixdd/ghgrab avatar
abhixdd/ghgrab

ghgrab pulls single files out of a Git forge without cloning it

A simple, pretty terminal tool that lets you browse and download files from GitHub, GitLab, Codeberg, Gitea, and Forgejo without leaving your CLI.

1,586 stars89 forksRustMIT

At a glance

What is it?
ghgrab is a Rust terminal UI that browses GitHub, GitLab, Codeberg, Gitea and Forgejo repositories and downloads only the files you select, with a separate subcommand for release assets. It trades scripting and automation for a point-and-pick interface, and several of its features only work against GitHub.
Who is it for?
Reach for ghgrab when you want one config file or one binary out of a large repository and would rather not wait for a clone, and when the target host is one of the five forges it supports. Skip it in scripted pipelines, on a self-hosted Gitea or Forgejo instance that needs release downloads or repository search, and in any locked-down environment where a postinstall step fetching a binary from GitHub releases is blocked.
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 7 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Grab one file instead of cloning the repository

The problem ghgrab addresses is narrow and real. Cloning a repository to read a single file costs you the full history transfer, and then you delete the directory. ghgrab replaces that with a browser: you point it at a repository, walk the tree, mark what you want, and it downloads just those paths.

The binary is Rust, built on `tokio` with the `full` feature set and a `ratatui` plus `crossterm` interface, with `clap` handling argument parsing. HTTP goes through `reqwest` 0.11 configured with `default-features = false` and `rustls-tls-native-roots`, so TLS uses the system root store rather than a bundled one. Source preview is handled by `syntect`, which brings syntax highlighting for the file types you open inside the interface.

Everything starts from the home screen. Typing `ghgrab` with no arguments opens it, and typing a keyword such as `ratatui` then pressing `Enter` switches into repository search mode. From there you filter the results and open one directly.

Five forges for browsing, one for everything else

This is the boundary that decides whether ghgrab fits your setup. Repository browsing and file or folder downloads work against GitHub, GitLab, Codeberg, Gitea, Forgejo and compatible self-hosted instances. Three capabilities do not follow: quick repository search from the home screen is GitHub only, the `release` command and its `rel` alias are GitHub only, and GitHub LFS pointer resolution is GitHub only.

That split has a practical consequence. On a self-hosted Gitea or Forgejo instance you can browse and pull files, but a repository that stores binaries through LFS will hand you pointer text rather than the object, because the LFS resolution path is not implemented outside GitHub. If your workflow needs release artifacts from an internal Forgejo, ghgrab stops at the file browser.

The extraction support in the release path is explicit about formats: `--extract` handles `.zip`, `.tar.gz`, `.tgz` and `.tar.xz`, backed by the `zip`, `tar`, `flate2` and `xz2` crates. Anything else downloads as an opaque file.

Five ways to install, two of which fetch a binary at install time

The README gives five installation paths and the repository carries the manifests for each of them.

bash
npm install -g @ghgrab/ghgrab

The npm package `@ghgrab/ghgrab` declares `os` as darwin, linux and win32 with `cpu` of x64 and arm64, exposes both `ghgrab` and the short alias `ghg` through `bin/ghgrab.js`, and runs `node scripts/install.js` as its postinstall step. That postinstall is where the platform binary is fetched, which some corporate npm policies reject outright.

The Python distribution takes a similar shape. `pyproject.toml` declares `requires-python = ">=3.7"`, classifies it as Development Status 4 - Beta, and registers `ghgrab = "ghgrab:main"` as a console script, but the `setup.py` in the repository does not compile anything. It resolves the platform, builds a release URL under the pinned `VERSION = "2.1.0"`, downloads the binary into a `ghgrab/` package directory, then verifies it against `checksums.json`. Files under 100,000 bytes are deleted and treated as a failed download.

Cargo compiles the Rust package, while pipx installs the Python wrapper:

bash
cargo install ghgrab
bash
pipx install ghgrab

Nix users can pin either the tip or a tag:

bash
nix run github:abhixdd/ghgrab
nix run "github:abhixdd/ghgrab/<tag>"

Arch users have a `yay -S ghgrab-bin` route backed by the PKGBUILD in the repository root.

Pointing it at a URL and overriding the download layout

Once installed, three flags control the browsing invocation. A repository URL is enough to open the tree directly:

bash
ghgrab https://github.com/rust-lang/rust
ghgrab https://gitlab.com/gitlab-org/gitlab
ghgrab https://codeberg.org/forgejo/forgejo
ghgrab https://github.com/rust-lang/rust --cwd --no-folder

`--cwd` forces the download into the current working directory, and `--no-folder` writes the files directly instead of creating a subfolder named after the repository. Left alone, ghgrab mirrors the selected paths under a repository-named directory, which is the safe default when you are pulling several files.

Authentication is handled by a single flag, `--token <TOKEN/AUTO/GH>`, where the literal values `auto` and `gh` both shell out to `gh auth token` at runtime. Passing it applies to that run only and does not write to the settings file, so there is no persistent credential to rotate later.

The `Cargo.toml` also depends on `rmcp` 1.7.0 with the `transport-io` feature, which suggests an MCP server surface alongside the TUI. The README does not document how to start or use it, so treat that as unconfirmed rather than as a documented feature.

How the release subcommand picks an artifact

`ghgrab rel <owner>/<repo>` is a different tool from the browser: it fetches the latest release, scores the assets against your detected OS and architecture, and takes the best match. If several assets score closely, it shows an interactive picker, where you type the asset number and press `Enter` to continue, or `q` and `Enter` to cancel.

bash
ghgrab rel sharkdp/bat
ghgrab rel sharkdp/bat --extract
ghgrab rel sharkdp/bat --tag v0.25.0
ghgrab rel sharkdp/bat --asset-regex "x86_64.*windows.*zip"
ghgrab rel BurntSushi/ripgrep --os windows --arch amd64
ghgrab rel starship/starship --prerelease

Selection is steerable from both ends. `--os` and `--arch` override detection, `--file-type` prefers `any`, `archive` or `binary` assets, `--tag` pins a specific release, and `--prerelease` widens the candidate set when no tag is given. `--asset-regex` is the escape hatch: supply a pattern that identifies exactly one artifact and the picker never appears.

The output side has two destinations that are easy to confuse. `--out <DIR>` sets where the download lands, while `--bin-path <DIR>` copies the selected file, or the binary extracted from the archive, into a directory on your PATH. The README's own example installs into `~/.local/bin`:

bash
ghgrab rel sharkdp/bat --extract --bin-path ~/.local/bin

What the release path does not offer is scripting. It is built for a human at a terminal, and the README documents no non-interactive output mode or JSON format.

Where ghgrab loses to a plain HTTP request

The honest comparison is not with another TUI. It is with the curl one-liner you would otherwise type, or with sparse checkout, or with the raw content API.

ghgrab's advantage is discovery and judgment. Finding the right file in an unfamiliar tree, previewing it, and pulling a matching release artifact are all things it does in one place. A curl command does none of that; it needs you to already know the path and branch.

Repository browsing requires a terminal interface, while release downloads can avoid its asset picker when the OS, architecture, tag, or asset regex determines the match. There is no documented batch mode that accepts a list of paths, and no output format meant for another program to parse. If you are automating, a shallow clone with `--depth 1` and a sparse checkout, or a direct download from the API, stays more predictable and adds no binary dependency.

The multi-forge support also has a testing dimension. The README names the hosts it works against but does not describe how version differences between GitLab, Gitea and Forgejo APIs are handled, so an unusual or heavily customized instance may expose paths the browser does not understand. Test the specific instance before depending on it.

MIT licensing, a Beta classifier, and a recent release run

The repository is not archived and the last push was on 2026-09-21, which is also the date of the v2.1.0 tag. Earlier tags are v2.0.2 on 2026-08-16 and v2.0.1 on 2026-05-20, so the 2.x line has seen three releases across about four months, with a longer gap before the 2.0.1 tag.

License terms are MIT across all three manifests: the `LICENSE` file, the `Cargo.toml` `license` field, the npm `license` field, and the `pyproject.toml` license text. MIT permits use, modification, redistribution and commercial use with the notice retained, including inside a proprietary product. That is a permissive license with no copyleft obligation, though the version numbers moving independently across Cargo, npm and Python at the moment of this writing means you should pin all three to the same tag rather than mixing latest resolutions.

Two metadata details are worth noticing if you automate installs. The Python distribution claims `requires-python = ">=3.7"` while the README's Rust badge lists 1.70, 1.75 and stable as the supported toolchains, and `pyproject.toml` self-classifies as Beta where the npm package has no such field. Treat the Python floor as a packaging claim rather than a tested matrix.

Editorial conclusion

Reach for ghgrab when you want one config file or one binary out of a large repository and would rather not wait for a clone, and when the target host is one of the five forges it supports. Skip it in scripted pipelines, on a self-hosted Gitea or Forgejo instance that needs release downloads or repository search, and in any locked-down environment where a postinstall step fetching a binary from GitHub releases is blocked. Verify first that the forge instance you need answers the browsing API ghgrab expects, by opening one repository URL with `ghgrab <url>` before writing anything against it.

Frequently asked questions

How do I install ghgrab?

The README lists five routes: `npm install -g @ghgrab/ghgrab`, `cargo install ghgrab`, `pipx install ghgrab`, `nix run github:abhixdd/ghgrab`, and `yay -S ghgrab-bin` on Arch. The npm and pipx paths install wrapper packages that download a prebuilt binary during install rather than compiling the Rust source.

Does ghgrab work with GitLab, Gitea and Forgejo?

Repository browsing and file or folder downloads do, including compatible self-hosted instances. Repository search from the home screen, the `release` and `rel` commands, and GitHub LFS resolution are GitHub only.

How do I download a release binary from ghgrab?

Run `ghgrab rel <owner>/<repo>`, which selects the asset matching your OS and architecture, or opens a picker if several match closely. Use `--tag`, `--asset-regex`, `--os`, `--arch` and `--file-type` to control the choice, and `--extract --bin-path <DIR>` to install the result into a directory.

What does the `--token` flag do in ghgrab?

`--token <TOKEN/AUTO/GH>` supplies a GitHub token for a single run without saving it to the settings file. The literal values `auto` and `gh` both call `gh auth token` at runtime.

Can ghgrab be used in scripts or CI?

The documented interface is an interactive terminal UI, and the README describes no non-interactive or JSON output mode. For automation, a shallow sparse clone or a direct API request is the more predictable route.

What license is ghgrab released under?

MIT, declared identically in the repository LICENSE file and in the Cargo, npm and Python manifests. Check the LICENSE file for the exact terms before redistributing the binary.

Official sources

  1. abhixdd/ghgrab on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/abhixdd-ghgrab.svg)](https://hysenlabs.com/projects/abhixdd-ghgrab)

Was this useful?