hf-hub
Rust client for the Hugging Face Hub API.
hf-hub provides a typed, ergonomic interface for interacting with the Hugging Face Hub from Rust. It is the Rust equivalent of the Python huggingface_hub library.
Both an async interface (HFClient, on by default) and a synchronous interface (HFClientSync, enabled via the blocking feature) are provided. The two mirror each other method-for-method.
Features
- Repository operations — query model, dataset, and space metadata; create, delete, update, and move repositories
- File operations — upload files and folders, download files, list repository trees, check file existence
- Commit operations — create commits with multiple file operations, list commit history, view diffs between revisions
- Branch and tag management — create and delete branches and tags, list refs
- User and organization info — whoami, user profiles, organization details, followers
- Streaming pagination — async list endpoints return
impl Stream<Item = Result<T>>for lazy, memory-efficient iteration; blocking counterparts collect intoVec<T> - Bucket operations — create, delete, list, and move buckets; upload, download, and delete files within buckets
- Xet high-performance transfers — support for Hugging Face's Xet storage backend
- Async or blocking — use
HFClientwith your own tokio runtime, orHFClientSyncfor synchronous callers (requires theblockingfeature)
Installation
Add to your Cargo.toml:
[]
= "1.0.0"
To use the synchronous interface, enable the blocking feature:
[]
= { = "1.0.0", = ["blocking"] }
CLI Installation
The hfrs command-line tool provides a terminal interface to the Hub. Install it with:
This builds in release mode by default. Once installed, run hfrs --help to see available commands.
Quick Start
Async
use HFClient;
use RepoInfo;
async
Blocking
Requires the blocking feature. HFClientSync manages a dedicated tokio runtime internally, so callers do not need their own.
use HFClientSync;
use RepoInfo;
The blocking handles (HFClientSync, HFRepositorySync, HFSpaceSync, HFBucketSync) mirror their async counterparts method-for-method. See the blocking_* examples in examples/ for runnable programs.
Usage Examples
List models by author
use StreamExt;
use HFClient;
async
Work with a repository handle
use HFClient;
use RepoInfo;
async
Download a file
use PathBuf;
use HFClient;
async
Upload a file
use HFClient;
use AddSource;
async
Create a repository
use HFClient;
async
Authentication
The client resolves authentication tokens in this order:
- Explicit token via
HFClientBuilder::token() HF_TOKENenvironment variable- Token file at the path specified by
HF_TOKEN_PATH - Default token file at
~/.cache/huggingface/token
Set HF_HUB_DISABLE_IMPLICIT_TOKEN to any non-empty value to disable automatic token resolution.
Configuration
| Environment Variable | Description |
|---|---|
HF_ENDPOINT |
Hub API endpoint (default: https://huggingface.co) |
HF_TOKEN |
Authentication token |
HF_TOKEN_PATH |
Path to token file |
HF_HOME |
Cache directory root (default: ~/.cache/huggingface) |
HF_HUB_DISABLE_IMPLICIT_TOKEN |
Disable automatic token loading |
HF_HUB_USER_AGENT_ORIGIN |
Custom User-Agent origin string |
Error Handling
All fallible operations return Result<T, HFError>. The HFError enum provides structured variants for common failure modes:
HFError::AuthRequired— 401 response, token is missing or invalidHFError::RepoNotFound— repository does not exist or is inaccessibleHFError::BucketNotFound— bucket does not exist or is inaccessibleHFError::EntryNotFound— file or path does not exist in the repository or bucketHFError::RevisionNotFound— branch, tag, or commit does not existHFError::Forbidden— 403 response, insufficient permissionsHFError::Conflict— 409 response, resource already exists or conflictsHFError::RateLimited— 429 response, too many requestsHFError::Http— other HTTP errors with status code, URL, and response body
WebAssembly support
hf-hub compiles for wasm32-unknown-unknown. On wasm the API surface is
the same call shape as native — client.model(owner, name).download_file_stream()…send().await —
but only the streaming download path is wired up; methods that touch the
filesystem (download_file, snapshot_download, upload_file, the
cache and buckets modules, the blocking wrappers) are gated behind
#[cfg(not(target_family = "wasm"))]. Pure-HTTP modules (repository,
spaces, users) and HTTP-only methods on HFRepository (exists,
info, list_*, etc.) are exposed on both targets.
Verify locally with ./scripts/verify_wasm.sh. CI runs the same check in
the wasm job of .github/workflows/rust.yml. The wasm/smoke/ crate is a
tiny wasm-bindgen library that exercises the wasm-safe surface end-to-end
(see wasm/smoke/src/lib.rs).
When modifying client, error, retry, xet, or
repository/download.rs, keep the wasm build green — reqwest's wasm
backend has a reduced API (no is_connect, no redirect() policy) and
its streams are !Send, and filesystem APIs must stay behind
#[cfg(not(target_family = "wasm"))] gates.
License
Apache-2.0