Skip to content

RFC: HF CLI Redesign — Consistency, Scalability, and Conventions #3792

@Wauplin

Description

@Wauplin

Disclaimer: written by Claude Code after a chat with me (@Wauplin) with some back and forth on the API design. Most of the "current issues" are things I told in them.


The hf CLI has grown to 13 command groups + 4 top-level commands with accumulated inconsistencies: mixed singular/plural naming, different verbs for the same action, and no clear boundary between "browse the Hub" and "manage my resources." Adding hf bucket brought this to a head — there's no clean way to add "list my buckets" without clashing with hf bucket ls (files) or creating a confusing hf buckets ls.

This RFC proposes design principles, concrete changes, and a backward-compatible migration plan. Inspired by the gh CLI.


1. Current Issues

1.1 Singular vs plural — no rule
Singular Plural
hf repo hf models, hf jobs
hf bucket hf endpoints, hf collections
hf cache, hf auth hf papers, hf skills

A new contributor can't predict the pattern.

1.2 Verb inconsistency across groups
Action Verbs used Where
List ls models, datasets, spaces, collections, cache, bucket, endpoints
ps jobs
list auth, repo tag
Details info models, datasets, spaces, collections
describe endpoints
inspect jobs
Remove delete repo, collections, bucket, endpoints
rm cache
1.3–1.10 More issues
  • 1.3 Bucket naming conflict: hf bucket ls lists files inside a bucket. How do we add "list my buckets"? hf buckets ls? No.
  • 1.4 hf collections mixes browse and manage: ls searches globally, but create/delete manages yours. No other group does this.
  • 1.5 hf repo-files: hyphenated name, single delete command. Should be hf repo delete-files.
  • 1.6 hf sync = hf bucket sync: same Python function registered twice.
  • 1.7 hf upload-large-folder: hyphenated top-level, clutters root.
  • 1.8 hf skills add: orphan command, AI jargon name, won't grow.
  • 1.9 Root bloat: 17 entries in hf --help, growing with each new resource type.
  • 1.10 No home for external tools: where does hf launch pi or hf run opencode go?

2. Design Principles

P1. Singular nouns for resource groupshf job run, hf endpoint deploy, hf collection create. Like gh repo, gh issue, gh pr.

P2. Separate global discovery from managementhf search models (browse the Hub) vs hf repo create (manage mine). Like gh search repos vs gh repo list.

P3. One verb per action, used everywherels (list), info (details), create, delete, update. Domain-specific verbs OK when they add clarity (run, deploy, cancel, pause).

P4. Clean root namespace — top-level = high-frequency actions (download, upload, sync). Everything else under hf <resource> <verb>.

P5. Extensibility — new resource = hf <singular-noun> group with standard verbs. External tools go under hf tool.


3. Proposed Changes

3.1 Singular nouns for all groups

hf jobshf job | hf endpointshf endpoint | hf collectionshf collection

(hf repo, hf bucket, hf cache, hf auth already singular — unchanged)

3.2 hf search — global discovery

Replaces all browse-only groups (hf models, hf datasets, hf spaces, hf papers) + the browse part of hf collections:

hf search models     [--search "llama"] [--author meta-llama] [--sort downloads]
hf search datasets   [--search "code"] [--filter text-classification]
hf search spaces     [--search "chatbot"]
hf search papers     [--date today] [--sort trending]
hf search collections [--owner nvidia]

Plurals after search because it reads naturally: "search models" (same as gh search repos).

info commands consolidate into hf repo info:

hf repo info meta-llama/Llama-3.2-1B-Instruct                    # defaults to model
hf repo info HuggingFaceFW/fineweb --repo-type dataset
hf repo info enzostvs/deepsite --repo-type space

A bit clunky for datasets/spaces (need --repo-type), but one command to learn instead of three, and model is the default.

Collection info stays at hf collection info (collections aren't repos).

Bucket ls conflict resolved: hf bucket ls is freed up for "list my buckets". With an argument, it lists files: hf bucket ls <bucket-id> (like ls vs ls <dir>).

3.3 Verb standardization

Current Proposed
hf jobs ps hf job ls
hf jobs inspect hf job info
hf endpoints describe hf endpoint info
hf cache rm hf cache delete
hf auth list hf auth ls
hf repo tag list hf repo tag ls

Old verbs kept as hidden aliases. hf job cancel stays — semantically different from delete.

3.4 Root cleanup

  • hf repo-files deletehf repo delete-files (absorbed into repo group)
  • hf sync → kept as top-level alias for hf bucket sync
  • hf upload-large-folder → keep working, deprecate later when hf upload handles large folders

3.5 External tools: hf tool

hf tool ls                              # List available/installed tools
hf tool install hf-skills --claude      # Install skills (replaces hf skills add)
hf tool run pi --backend llama.cpp      # Launch Pi
hf tool run opencode --model Kimi-K2.5  # Run OpenCode
hf tool remove <name>                   # Uninstall

Why hf tool over hf ext/hf run/hf agent/hf launch: "tool" is generic, clear, and extensible. "Extension" implies CLI plugins. "Agent" is jargon. "Run" conflicts with hf job run. "Launch" only covers running, not installing/managing.


4. hf --help — Before and After

Before (17 entries, mixed singular/plural, mixed purpose):

auth, bucket, cache, collections, datasets, download, endpoints,
jobs, models, papers, repo, repo-files, skills, spaces, sync,
upload, upload-large-folder

After (12 entries, consistent singular, clear separation):

download, upload, sync, search, auth, repo, bucket, collection,
job, endpoint, cache, tool

5. Migration Strategy

Phase When What
1. Add new names Next release Both old and new work, no warnings. Documentation uses new names only.
2. Deprecation warnings Release after Old names emit one-time warning, hidden from --help.
3. Removal Major version Old names removed.
Full before/after command map

Search (replaces models/datasets/spaces/papers):

Before After
hf models ls hf search models
hf models info <id> hf repo info <id>
hf datasets ls hf search datasets
hf datasets info <id> hf repo info <id> --repo-type dataset
hf spaces ls hf search spaces
hf spaces info <id> hf repo info <id> --repo-type space
hf papers ls hf search papers

Collections:

Before After
hf collections ls hf search collections
hf collections info/create/update/delete/add-item/... hf collection info/create/update/delete/add-item/...

Jobs:

Before After
hf jobs run hf job run
hf jobs ps hf job ls
hf jobs inspect hf job info
hf jobs logs/stats/cancel/hardware hf job logs/stats/cancel/hardware
hf jobs uv run hf job uv run
hf jobs scheduled ps hf job scheduled ls
hf jobs scheduled inspect hf job scheduled info
hf jobs scheduled run/delete/suspend/resume hf job scheduled run/delete/suspend/resume

Endpoints:

Before After
hf endpoints ls hf endpoint ls
hf endpoints describe hf endpoint info
hf endpoints deploy/update/delete/pause/resume/scale-to-zero hf endpoint deploy/update/delete/pause/resume/scale-to-zero
hf endpoints catalog ls/deploy hf endpoint catalog ls/deploy
hf endpoints list-catalog (removed — hidden duplicate)

Repo:

Before After
hf repo create/delete/move/settings unchanged
hf repo branch create/delete unchanged
hf repo tag list hf repo tag ls
hf repo-files delete hf repo delete-files
(new) hf repo info <id> [--repo-type]

Cache: hf cache rmhf cache delete. Rest unchanged.
Auth: hf auth listhf auth ls. Rest unchanged.
Skills: hf skills addhf tool install hf-skills.


6. Guidelines for New Commands

hf <verb>                           # Top-level action (download, upload, sync)
hf <resource> <verb>                # Resource management (repo create, job run)
hf <resource> <sub-resource> <verb> # Nested resource (repo tag create)
hf search <resources>               # Global discovery (search models)
hf tool <verb> <name>               # External tools (tool install, tool run)
  • Resource groups: singular noun + canonical verbs (ls, info, create, delete, update)
  • Top-level: only high-frequency actions (would most hf users run this regularly?)
  • Domain-specific verbs OK when they genuinely add clarity (deploy, cancel, run, pause)
  • External tools/integrations: hf tool

7. Open Questions

Q1: hf search vs per-resource groups?
Alternative: keep hf model ls (singular) for browsing instead of hf search models. Simpler mental model, but hf model ls looks like "list MY models" (like gh repo list). Recommendation: hf search makes the global nature explicit.

Q2: hf bucket ls overloadinghf bucket ls (my buckets) vs hf bucket ls <id> (files in bucket, like ls vs ls <dir>)? Or a separate verb like hf bucket tree <id>?

Q3: hf tool run or top-level? — Should installed tools register as top-level (hf pi) like gh extensions? Recommendation: start with hf tool run <name>, revisit later.

Q4: Migration timeline — Conservative (Phase 2 in 6 months)? Moderate (Phase 2 next release)? Aggressive (Phase 1+2 together)?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions