The fastest, smartest way to download models and datasets from the HuggingFace Hub.
A single Rust binary with a real-time terminal dashboard, multi-connection chunked downloads, crash-safe resume, SHA-256 verification, GGUF quantization analysis, and an interactive quant picker.
hfd TheBloke/Mistral-7B-Instruct-v0.2-GGUF:q4_k_m
Files land in ~/models/<org>/<repo>/... as plain, ready-to-use files.
- Multi-connection downloads — up to 64 parallel HTTP range requests per file, written with positional I/O (no locks, no gaps).
- Concurrent files — download several files at once with a global connection budget.
- Resume anything — a
<file>.hfd-partsidecar records every chunk. Kill the process, lose the network, or reboot; the next run continues exactly where it stopped. - Integrity by default available — stream SHA-256 verification against the
LFS object hash with
--verify. - Best-in-class TUI — live overall gauge, per-file bars, speed, ETA, a navigable detail pane with a Mercedes-style radial speedometer, pause/resume and cancel.
- Interactive GGUF picker — quality stars, RAM estimates, a “recommended” badge (Q4_K_M), multi-select, and one keystroke to download.
- Datasets too — full support for
datasets/repositories. - Private & gated repos —
--tokenorHF_TOKEN. - Mirrors & proxies —
--endpoint https://hf-mirror.com, HTTP/SOCKS5 proxies via--proxyor environment variables.
curl -fsSL https://raw.githubusercontent.com/iamhsouna/hfd/master/install.sh | bashThe installer detects your OS and architecture, installs the required
dependencies, and puts hfd on your PATH (in ~/.local/bin by default).
It works on macOS, Ubuntu/Debian, Arch Linux, Fedora, and openSUSE.
It prefers a prebuilt release binary and automatically falls back to building from source if none is available for your platform.
# Build from source instead
curl -fsSL .../install.sh | bash -s -- --from-source
# Choose the install directory
curl -fsSL .../install.sh | bash -s -- --bin-dir /usr/local/bin
# Pin a release
curl -fsSL .../install.sh | bash -s -- --version v0.1.0Installer flags: --from-source, --version TAG, --bin-dir DIR,
--no-modify-path, --no-deps, --help.
git clone https://github.com/iamhsouna/hfd && cd hfd
cargo build --release
install -m 755 target/release/hfd ~/.local/bin/hfdRequirements: a recent stable Rust toolchain.
hfd update # update to the latest release
hfd update --check # only check, do not install
hfd update --tag v0.1.0hfd update downloads the matching prebuilt binary from GitHub Releases,
verifies its checksum when available, and atomically replaces the running
executable.
# Download a whole model (default command)
hfd sshleifer/tiny-gpt2
# Download just one file (exact name, or any part of the path)
hfd download ISTA-DASLab/Qwen3.8-27B-GSQ-RCO-GGUF Qwen3.8-27B-GSQ-RCO-IQ3_S-mtp.gguf
# Or with an include pattern (-F matches any part of the path)
hfd download owner/repo -F q4_k_m
hfd download owner/repo -F IQ3_S-mtp.gguf
# Pick a quantization interactively
hfd analyze -i TheBloke/Mistral-7B-Instruct-v0.2-GGUF
# Download one quant directly
hfd TheBloke/Mistral-7B-Instruct-v0.2-GGUF:q4_k_m
# Several quants at once
hfd TheBloke/Mistral-7B-Instruct-v0.2-GGUF:q4_k_m,q5_k_m
# Preview without downloading
hfd download owner/repo --dry-run
# Verify hashes as you go
hfd download owner/repo --verify
# A dataset
hfd download squad --dataset
# Search the Hub
hfd search "code llama" -l 10hfd tui # home menu: search, browse local, quit
hfd tui "qwen gguf" # start with a search
hfd tui Qwen/Qwen2.5-7B-GGUF # open a repository directly
hfd tui --dataset squad # search datasetsThe browser lets you search the Hub, open a repository, pick exactly which files or quantizations to download (with quality stars and RAM estimates), watch the live transfer dashboard, and browse everything already downloaded locally — all without leaving the terminal.
| Screen | Keys |
|---|---|
| Home | ↑/↓ move, Enter select, q quit |
| Search | type a query or org/name, Enter search/open, Ctrl-T models/datasets, ↓ into results |
| Results | ↑/↓ move, Enter open repository, Esc back to input |
| Files | Space select, a all, n none, Enter download, o open folder, Esc back |
| Download | p pause/resume, c cancel, ? help, q back |
| Local | ↑/↓ move, Enter details, o open folder, Esc back |
| Command | Description |
|---|---|
download |
Download a model or dataset (the default command) |
analyze |
Inspect a repository; -i opens the GGUF picker |
search |
Search models or datasets |
list |
List everything downloaded under the output directory |
info |
Show details of a downloaded repository |
config |
Show, edit, or locate the configuration file |
tui |
Open the interactive browser (search, pick files, download, browse local) |
update |
Update hfd to the latest release (--check, --force, --tag) |
version |
Show version information |
| Flag | Default | Description |
|---|---|---|
-o, --output <DIR> |
~/models |
Output directory (--local-dir is an alias) |
-c, --connections <N> |
8 |
Parallel connections per file |
--max-active <N> |
3 |
Files downloaded concurrently |
-b, --revision <REV> |
main |
Branch, tag, or commit |
-t, --token <TOKEN> |
— | HuggingFace access token |
--proxy <URL> |
— | http://, https://, socks5://, socks5h:// |
--endpoint <URL> |
https://huggingface.co |
API endpoint / mirror |
--verify |
off | Verify SHA-256 of downloaded files |
--no-tui / --tui |
auto | Disable / force the dashboard |
download also accepts -F/--filter (include patterns), -E/--exclude,
--dataset, --dry-run, --force, and --json.
analyze accepts -i/--interactive, --dataset, --json, and --download.
~/models/
└── TheBloke/
└── Mistral-7B-Instruct-v0.2-GGUF/
├── mistral-7b-instruct-v0.2.Q4_K_M.gguf
└── hfd.yaml # manifest: repo, commit, files, sizes, hashes
Every successful download writes an hfd.yaml manifest. hfd list and
hfd info read these to report what you have and where.
Interrupted transfers leave a <file>.hfd-part sidecar next to the partial
file. It records the file size, etag, and the byte offset of every chunk.
hfd download owner/repo
# ... interrupt ...
hfd download owner/repo # picks up exactly where it stoppedIf the remote file changed (different size or etag), the partial state is discarded and the download restarts cleanly.
| Key | Action |
|---|---|
q / Esc |
Quit (saves resume state) |
p / Space |
Pause / resume all transfers |
↑ ↓ / k j |
Select a file |
g / G |
Jump to first / last |
c |
Cancel all downloads |
o |
Open the output folder |
? / h |
Toggle help |
~/.config/hfd/config.toml (created on hfd config set):
output_dir = "~/models"
endpoint = "https://huggingface.co"
connections = 8
max_active = 3
verify = false
tui = true
# token = "hf_xxx"
# proxy = "http://proxy:8080"hfd config show
hfd config set connections 16
hfd config pathEnvironment overrides: HF_TOKEN, HF_ENDPOINT, HFD_OUTPUT_DIR,
HTTP_PROXY / HTTPS_PROXY.
- The repository tree is fetched from
/api/{models|datasets}/{repo}/tree/{rev}with pagination, yielding each file’s size and LFS SHA-256. - Each file is probed with a
Range: bytes=0-0request to detect range support and the exact size/etag. - Files larger than 4 MiB are split into aligned chunks (one per connection)
and fetched concurrently with
Rangerequests; every write is a positionalpwrite, so chunks never interfere. - Partial state is flushed to the
.hfd-partsidecar once per second and on every exit path, making crashes cheap. - When every chunk is present the sidecar is removed; with
--verifythe file is streamed through SHA-256 and compared to the LFS hash.
cargo test # unit tests
cargo clippy # lints
cargo fmt # formattingApache-2.0.