Skip to main content

Downloading models

NobodyWho can either load a model from a path on disk or download it for you on first use, caching it for subsequent runs. This page covers the available model path formats, how to access gated/private models, how to observe a download in progress, and how to inspect what's already in the local cache.

Supported model path formats​

The modelPath option to Chat.fromPath and downloadModel accepts:

FormExampleNotes
HuggingFace referencehf:owner/repo/file.ggufDownloaded and cached on first use
llama.cpp-style referenceowner/repo:quantizationDownloaded and cached on first use
HTTPS URLhttps://example.com/model.ggufDownloaded and cached on first use
Local path./model.ggufUsed as-is

The HuggingFace prefix is case-insensitive and the // is optional — hf:, hf://, huggingface:, and huggingface:// all mean the same thing. Remote models are downloaded to the platform cache directory on first load and re-used on subsequent runs.

The llama.cpp-style reference takes no prefix, and names a HuggingFace repo whose name must end in -GGUF — the convention llama.cpp relies on to work out the filename. NobodyWho resolves it the same way, so ggml-org/gemma-3-1b-it-GGUF:Q8_0 fetches gemma-3-1b-it-Q8_0.gguf from the ggml-org/gemma-3-1b-it-GGUF repo. Both the -GGUF suffix and the quantization are required; without them the string is read as a local path rather than a download. Note: llama.cpp will take the first model in the repo if there is no exact match for the quantization, but NobodyWho will fail with an error if the quantization is not found.

Android permissions (React Native only)​

Loading a model from hf:// or https:// needs network access. The React Native app template already declares the internet permission in android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />

If your project has removed it, add it back. Apps that only load models from local paths need no network permission.

Downloading a gated model​

Some HuggingFace models are private or gated by a license you need to accept. In both cases you need to be authorized to download the model weights.

You can manually download the GGUF file via your web browser, place it on the device, and then point Chat.fromPath at the local path:

import { Chat } from "react-native-nobodywho";

const chat = await Chat.fromPath({ modelPath: "./model.gguf" });

Or use downloadModel with an Authorization header:

import { downloadModel, Chat } from "react-native-nobodywho";

const modelPath = await downloadModel({
modelPath: "huggingface:NobodyWho/Qwen_Qwen3-0.6B-GGUF/Qwen_Qwen3-0.6B-Q4_K_M.gguf",
headers: { Authorization: "Bearer your_hf_token" },
});

const chat = await Chat.fromPath({ modelPath });

You can generate a HuggingFace token in your account settings.

Tracking download progress​

When loading a remote model, pass an onDownloadProgress option to observe the download. It receives (downloaded, total) byte counts, is throttled to roughly 10 Hz with a guaranteed final emit on completion, and is not called for cached or local files.

const chat = await Chat.fromPath({
modelPath: "huggingface:NobodyWho/Qwen_Qwen3-0.6B-GGUF/Qwen_Qwen3-0.6B-Q4_K_M.gguf",
onDownloadProgress: (downloaded, total) => {
console.log(`${downloaded} / ${total} bytes`);
},
});

Inspecting the model cache​

getCachedModels() returns every .gguf model in NobodyWho's cache directory, paired with its size in bytes. This is the same cache used by downloadModel and by Chat.fromPath's huggingface: paths.

import { getCachedModels } from "react-native-nobodywho";

for (const model of getCachedModels()) {
console.log(`${model.path}: ${Number(model.size)} bytes`);
}

Each entry has:

  • path: string — absolute path to the cached .gguf file
  • size: bigint — size in bytes (the underlying Rust u64, exposed as JavaScript bigint)

The array is empty if nothing has been downloaded yet. The call throws if the cache directory cannot be read.