Buckets:

HuggingFaceDocBuilder's picture
download
raw
48.7 kB
<meta charset="utf-8" /><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Create a CLI extension&quot;,&quot;local&quot;:&quot;create-a-cli-extension&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Overview&quot;,&quot;local&quot;:&quot;overview&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Create a shell script extension&quot;,&quot;local&quot;:&quot;create-a-shell-script-extension&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Minimal example&quot;,&quot;local&quot;:&quot;minimal-example&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Tips for shell script extensions&quot;,&quot;local&quot;:&quot;tips-for-shell-script-extensions&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Create a Python extension&quot;,&quot;local&quot;:&quot;create-a-python-extension&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Minimal example&quot;,&quot;local&quot;:&quot;minimal-example&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;How Python extensions are installed&quot;,&quot;local&quot;:&quot;how-python-extensions-are-installed&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Add a description&quot;,&quot;local&quot;:&quot;add-a-description&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Make your extension discoverable&quot;,&quot;local&quot;:&quot;make-your-extension-discoverable&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Test your extension&quot;,&quot;local&quot;:&quot;test-your-extension&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Naming rules&quot;,&quot;local&quot;:&quot;naming-rules&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Existing extensions&quot;,&quot;local&quot;:&quot;existing-extensions&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}">
<link href="/docs/huggingface_hub/pr_4136/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/entry/start.a4ff766c.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/chunks/scheduler.0cf4ef2e.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/chunks/singletons.3fe09ff3.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/chunks/paths.2a1c8317.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/entry/app.86186fdc.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/chunks/preload-helper.f9690b41.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/chunks/index.abc433bf.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/nodes/0.ddad4902.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/chunks/each.e59479a4.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/nodes/6.4dbdd2c8.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/chunks/CopyLLMTxtMenu.7f1298e2.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/chunks/MermaidChart.svelte_svelte_type_style_lang.4040d144.js">
<link rel="modulepreload" href="/docs/huggingface_hub/pr_4136/en/_app/immutable/chunks/CodeBlock.c96dacd5.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Create a CLI extension&quot;,&quot;local&quot;:&quot;create-a-cli-extension&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Overview&quot;,&quot;local&quot;:&quot;overview&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Create a shell script extension&quot;,&quot;local&quot;:&quot;create-a-shell-script-extension&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Minimal example&quot;,&quot;local&quot;:&quot;minimal-example&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Tips for shell script extensions&quot;,&quot;local&quot;:&quot;tips-for-shell-script-extensions&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Create a Python extension&quot;,&quot;local&quot;:&quot;create-a-python-extension&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Minimal example&quot;,&quot;local&quot;:&quot;minimal-example&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;How Python extensions are installed&quot;,&quot;local&quot;:&quot;how-python-extensions-are-installed&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Add a description&quot;,&quot;local&quot;:&quot;add-a-description&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Make your extension discoverable&quot;,&quot;local&quot;:&quot;make-your-extension-discoverable&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Test your extension&quot;,&quot;local&quot;:&quot;test-your-extension&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Naming rules&quot;,&quot;local&quot;:&quot;naming-rules&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Existing extensions&quot;,&quot;local&quot;:&quot;existing-extensions&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg></button></div> </div> <h1 class="relative group"><a id="create-a-cli-extension" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#create-a-cli-extension"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Create a CLI extension</span></h1> <p data-svelte-h="svelte-1q5akkc">The <code>hf</code> CLI supports extensions, custom commands provided by the community that integrate seamlessly
into the CLI. Extensions are hosted as public GitHub repositories and can be installed with a single command.
Once installed, they appear as top-level <code>hf</code> commands just like built-in ones.</p> <p data-svelte-h="svelte-1byfhlq">This system is inspired by <a href="https://docs.github.com/en/github-cli/github-cli/creating-github-cli-extensions" rel="nofollow">GitHub CLI extensions</a>.
In this guide, you will learn how to create your own extension, publish it, and make it discoverable.</p> <blockquote class="tip" data-svelte-h="svelte-1e0lle9"><p>For user-facing documentation on installing and managing extensions, see the
<a href="../package_reference/cli#hf-extensions">CLI reference for <code>hf extensions</code></a>.</p></blockquote> <h2 class="relative group"><a id="overview" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#overview"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Overview</span></h2> <p data-svelte-h="svelte-xiu1ic">There are two types of extensions:</p> <ol data-svelte-h="svelte-1ldrpym"><li><strong>Shell script extensions</strong>: a single executable file (bash script, compiled binary, etc.) placed at the
root of the repository.</li> <li><strong>Python extensions</strong>: a standard Python package with a <code>pyproject.toml</code>. Installed in an isolated virtual
environment so dependencies don’t conflict with the user’s system.</li></ol> <p data-svelte-h="svelte-d6kjka">Both types share the same conventions:</p> <ul data-svelte-h="svelte-hgqec"><li>The GitHub repository <strong>must</strong> be named <code>hf-&lt;name&gt;</code> (e.g., <code>hf-claude</code>, <code>hf-mem</code>).</li> <li>Once installed, users run the extension with <code>hf &lt;name&gt;</code> (e.g., <code>hf claude</code>).</li> <li>The extension is listed in <code>hf --help</code> under “Extension commands”.</li></ul> <p data-svelte-h="svelte-eu3lkc">When a user runs <code>hf extensions install [OWNER/]hf-&lt;name&gt;</code>, the system first looks for a binary/script file
named <code>hf-&lt;name&gt;</code> at the repository root. If found, it installs as a shell script extension. Otherwise, it
falls back to installing the repo as a Python package.</p> <h2 class="relative group"><a id="create-a-shell-script-extension" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#create-a-shell-script-extension"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Create a shell script extension</span></h2> <p data-svelte-h="svelte-1b6g6do">A shell script extension is the simplest type. You only need a GitHub repository with an executable file
named <code>hf-&lt;name&gt;</code> at the root.</p> <h3 class="relative group"><a id="minimal-example" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#minimal-example"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Minimal example</span></h3> <p data-svelte-h="svelte-5cvxht">Create a repository named <code>hf-hello</code> on GitHub with a single file:</p> <p data-svelte-h="svelte-1v30s5a"><strong><code>hf-hello</code></strong> (at the repository root):</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">#!/usr/bin/env bash</span>
<span class="hljs-built_in">set</span> -euo pipefail
<span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;Hello from hf-hello extension!&quot;</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;Arguments: <span class="hljs-variable">$@</span>&quot;</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1mt4kpb">That’s it! Users can now install and run it:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">&gt;&gt;&gt; </span>hf extensions install &lt;your-username&gt;/hf-hello
<span class="hljs-meta">&gt;&gt;&gt; </span>hf hello
Hello from hf-hello extension!
Arguments:<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="tips-for-shell-script-extensions" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#tips-for-shell-script-extensions"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Tips for shell script extensions</span></h3> <ul data-svelte-h="svelte-cqrf4j"><li>Always start with a shebang (<code>#!/usr/bin/env bash</code>) and <code>set -euo pipefail</code> for safety.</li> <li>The script receives all extra arguments passed by the user. For example, <code>hf hello --name world</code>
passes <code>--name world</code> to the script.</li> <li>You can access the user’s Hugging Face token via the <code>HF_TOKEN</code> environment variable if they are logged in.</li> <li>Add a <code>manifest.json</code> at the repository root to provide a description (see <a href="#add-a-description">Add a description</a>).</li> <li>External dependencies (e.g., <code>fzf</code>, <code>jq</code>, etc.) are <strong>not</strong> installed automatically with your extension. Check
for required tools at the start of your script and fail gracefully with a helpful error message if they are missing.</li></ul> <blockquote class="tip" data-svelte-h="svelte-mm9rr5"><p>For a real-world example, see <a href="https://github.com/hanouticelina/hf-claude" rel="nofollow">hanouticelina/hf-claude</a>
a shell script extension that launches Claude Code with HF Inference Providers.</p></blockquote> <h2 class="relative group"><a id="create-a-python-extension" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#create-a-python-extension"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Create a Python extension</span></h2> <p data-svelte-h="svelte-awt6se">Python extensions are full Python packages installed in an isolated virtual environment. This is the best
choice when your extension has Python dependencies or more complex logic.</p> <h3 class="relative group"><a id="minimal-example" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#minimal-example"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Minimal example</span></h3> <p data-svelte-h="svelte-16z2inb">Create a repository named <code>hf-hello</code> on GitHub with this structure:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->hf-hello/
├── pyproject<span class="hljs-selector-class">.toml</span>
└── <span class="hljs-attribute">src</span>/
└── hf_hello/
├── __init__<span class="hljs-selector-class">.py</span>
└── cli.py<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-zbdyl4"><strong><code>pyproject.toml</code></strong>:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-section">[build-system]</span>
<span class="hljs-attr">requires</span> = [<span class="hljs-string">&quot;setuptools&gt;=64&quot;</span>]
<span class="hljs-attr">build-backend</span> = <span class="hljs-string">&quot;setuptools.backends._legacy:_Backend&quot;</span>
<span class="hljs-section">[project]</span>
<span class="hljs-attr">name</span> = <span class="hljs-string">&quot;hf-hello&quot;</span>
<span class="hljs-attr">version</span> = <span class="hljs-string">&quot;0.1.0&quot;</span>
<span class="hljs-attr">description</span> = <span class="hljs-string">&quot;A hello-world hf CLI extension&quot;</span>
<span class="hljs-attr">requires-python</span> = <span class="hljs-string">&quot;&gt;=3.10&quot;</span>
<span class="hljs-section">[project.scripts]</span>
<span class="hljs-attr">hf-hello</span> = <span class="hljs-string">&quot;hf_hello.cli:main&quot;</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-f4eoa2"><strong><code>src/hf_hello/cli.py</code></strong>:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> sys
<span class="hljs-keyword">def</span> <span class="hljs-title function_">main</span>():
<span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;Hello from hf-hello extension!&quot;</span>)
<span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Arguments: <span class="hljs-subst">{sys.argv[<span class="hljs-number">1</span>:]}</span>&quot;</span>)
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:
main()<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1t303pd">The critical part is the <code>[project.scripts]</code> entry point: it <strong>must</strong> be named <code>hf-&lt;name&gt;</code> (here, <code>hf-hello</code>).
This is how the <code>hf</code> CLI discovers and executes your extension.</p> <p data-svelte-h="svelte-utlp0q">Users install and run it the same way:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">&gt;&gt;&gt; </span>hf extensions install &lt;your-username&gt;/hf-hello
<span class="hljs-meta">&gt;&gt;&gt; </span>hf hello
Hello from hf-hello extension!
Arguments: []<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="how-python-extensions-are-installed" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#how-python-extensions-are-installed"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>How Python extensions are installed</span></h3> <p data-svelte-h="svelte-w09xbp">When a user installs a Python extension, the following happens:</p> <ol data-svelte-h="svelte-1xrsigc"><li>A virtual environment is created at <code>~/.local/share/hf/extensions/hf-&lt;name&gt;/venv/</code>.</li> <li>Your package is installed via <code>pip install</code> from the GitHub repo archive.</li> <li>The system verifies that a <code>hf-&lt;name&gt;</code> console script was created in the venv.</li></ol> <p data-svelte-h="svelte-bb5g4y">This means your extension’s dependencies are fully isolated — they won’t conflict with the user’s
other Python packages.</p> <blockquote class="tip" data-svelte-h="svelte-ep6lu7"><p>For a real-world example, see <a href="https://github.com/alvarobartt/hf-mem" rel="nofollow">alvarobartt/hf-mem</a>
a Python extension that estimates inference memory requirements for HF models.</p></blockquote> <h2 class="relative group"><a id="add-a-description" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#add-a-description"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Add a description</span></h2> <p data-svelte-h="svelte-uiws1j">A description helps users understand what your extension does. It appears in <code>hf extensions list</code>
and in <code>hf --help</code>.</p> <p data-svelte-h="svelte-lkxxfv">The system looks for a description in the following order:</p> <ol data-svelte-h="svelte-h3foui"><li><strong><code>manifest.json</code></strong> at the repository root:</li></ol> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-punctuation">{</span>
<span class="hljs-attr">&quot;description&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;A short description of what your extension does&quot;</span>
<span class="hljs-punctuation">}</span><!-- HTML_TAG_END --></pre></div> <ol start="2" data-svelte-h="svelte-1o3b1sx"><li><strong><code>pyproject.toml</code></strong> <code>description</code> field (for Python extensions):</li></ol> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-section">[project]</span>
<span class="hljs-attr">description</span> = <span class="hljs-string">&quot;A short description of what your extension does&quot;</span><!-- HTML_TAG_END --></pre></div> <ol start="3" data-svelte-h="svelte-ukpmjm"><li><strong>GitHub repository description</strong> (the “About” field on the repo page).</li></ol> <p data-svelte-h="svelte-mfqx6s">For Python extensions, setting <code>description</code> in <code>pyproject.toml</code> is the most natural approach.
For shell script extensions, use a <code>manifest.json</code> file or set the GitHub repository description.</p> <h2 class="relative group"><a id="make-your-extension-discoverable" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#make-your-extension-discoverable"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Make your extension discoverable</span></h2> <p data-svelte-h="svelte-el4lx">To help users find your extension, add the <strong><code>hf-extension</code></strong> topic to your GitHub repository:</p> <ol data-svelte-h="svelte-1mytaaf"><li>Go to your repository on GitHub.</li> <li>Click the gear icon next to “About” on the right sidebar.</li> <li>Under “Topics”, add <code>hf-extension</code>.</li></ol> <p data-svelte-h="svelte-1p8m405">This is a community convention that makes it easy to browse all available extensions on the
<a href="https://github.com/topics/hf-extension" rel="nofollow">hf-extension topic page</a>.</p> <p data-svelte-h="svelte-zohpf6">Users can then discover your extension directly from the CLI with <code>hf extensions search</code>, which lists
all GitHub repositories tagged with the <code>hf-extension</code> topic, sorted by stars:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">&gt;&gt;&gt; </span>hf extensions search
NAME REPO STARS DESCRIPTION INSTALLED
------ ----------------------- ----- ----------------------------------- ---------
claude hanouticelina/hf-claude 2 Extension <span class="hljs-keyword">for</span> `hf` CLI to launch... <span class="hljs-built_in">yes</span>
agents hanouticelina/hf-agents HF extension to run <span class="hljs-built_in">local</span> coding...<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1ggbfhp">The <code>INSTALLED</code> column shows which extensions are already installed locally. From there, users can
install any listed extension with <code>hf extensions install &lt;repo&gt;</code>.</p> <h2 class="relative group"><a id="test-your-extension" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#test-your-extension"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Test your extension</span></h2> <p data-svelte-h="svelte-w2h06i">During development, you can install your extension directly from your GitHub repository:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment"># Install from your repo</span>
<span class="hljs-meta">&gt;&gt;&gt; </span>hf extensions install &lt;your-username&gt;/hf-&lt;name&gt;
<span class="hljs-comment"># Run it</span>
<span class="hljs-meta">&gt;&gt;&gt; </span>hf &lt;name&gt;
<span class="hljs-comment"># Reinstall after making changes (push to GitHub first)</span>
<span class="hljs-meta">&gt;&gt;&gt; </span>hf extensions install &lt;your-username&gt;/hf-&lt;name&gt; --force
<span class="hljs-comment"># List installed extensions</span>
<span class="hljs-meta">&gt;&gt;&gt; </span>hf extensions list
<span class="hljs-comment"># Remove when done</span>
<span class="hljs-meta">&gt;&gt;&gt; </span>hf extensions remove &lt;name&gt;<!-- HTML_TAG_END --></pre></div> <blockquote class="tip" data-svelte-h="svelte-108y91p"><p>Use <code>--force</code> to overwrite a previously installed version when testing updates.</p></blockquote> <h2 class="relative group"><a id="naming-rules" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#naming-rules"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Naming rules</span></h2> <p data-svelte-h="svelte-1ab6iip">Extension names must follow these rules:</p> <ul data-svelte-h="svelte-1kb84n6"><li>The GitHub repository must be named <code>hf-&lt;name&gt;</code>.</li> <li><code>&lt;name&gt;</code> must start with a letter or digit.</li> <li><code>&lt;name&gt;</code> can contain letters, digits, <code>.</code>, <code>_</code>, and <code>-</code>.</li> <li><code>&lt;name&gt;</code> cannot conflict with a built-in <code>hf</code> command (e.g., <code>download</code>, <code>upload</code>, <code>auth</code>).</li></ul> <p data-svelte-h="svelte-1yo8418">When installing, users can either specify the full <code>OWNER/hf-&lt;name&gt;</code> or just <code>hf-&lt;name&gt;</code> (which
defaults to the <code>huggingface</code> organization).</p> <h2 class="relative group"><a id="existing-extensions" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#existing-extensions"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Existing extensions</span></h2> <p data-svelte-h="svelte-1m4fjse">Here are some community extensions you can use as reference:</p> <table data-svelte-h="svelte-1tjjp8o"><thead><tr><th>Extension</th> <th>Type</th> <th>Description</th></tr></thead> <tbody><tr><td><a href="https://github.com/hanouticelina/hf-claude" rel="nofollow">hanouticelina/hf-claude</a></td> <td>Shell script</td> <td>Launch Claude Code with HF Inference Providers</td></tr> <tr><td><a href="https://github.com/alvarobartt/hf-mem" rel="nofollow">alvarobartt/hf-mem</a></td> <td>Python</td> <td>Estimate inference memory requirements for HF models</td></tr></tbody></table> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/huggingface_hub/blob/main/docs/source/en/guides/cli-extensions.md" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg> <span data-svelte-h="svelte-zjs2n5"><span class="underline">Update</span> on GitHub</span></a> <p></p>
<script>
{
__sveltekit_6sqddk = {
assets: "/docs/huggingface_hub/pr_4136/en",
base: "/docs/huggingface_hub/pr_4136/en",
env: {}
};
const element = document.currentScript.parentElement;
const data = [null,null];
Promise.all([
import("/docs/huggingface_hub/pr_4136/en/_app/immutable/entry/start.a4ff766c.js"),
import("/docs/huggingface_hub/pr_4136/en/_app/immutable/entry/app.86186fdc.js")
]).then(([kit, app]) => {
kit.start(app, element, {
node_ids: [0, 6],
data,
form: null,
error: null
});
});
}
</script>

Xet Storage Details

Size:
48.7 kB
·
Xet hash:
2613a3e9f9125f4dd5f2be0e250c8c4bed574919fb8c87aceb4d405105f59fe9

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.