A SwarmUI extension that enhances the model download utility allowing you to browse from popular model sites
C#
3
63 commits
updated Sep 28, 2026

A full-featured model browser for SwarmUI's Utilities > Model Downloader tab. Search, preview, and download models from CivitAI, Hugging Face, and Hartsy without leaving SwarmUI or hand-typing a URL.
[!NOTE] This extension enhances SwarmUI's built-in Model Downloader. It does not replace it. The manual URL download workflow on the left is still core SwarmUI, just reorganized and given a few extra conveniences (a folder browser, a destination preview). The model browser on the right is new.

Three providers, one interface: switch between Hartsy, CivitAI, and Hugging Face with a dropdown; each keeps its own search/filter state
Filters: model type / architecture, base model, sort, tags, and (CivitAI only) NSFW, per provider. See Providers for exactly what each one supports
Page or cursor pagination, whichever the active provider's API uses
Model cards: thumbnail, title, creator, download count, and type/base-model badges, plus a version/format picker on cards that have more than one downloadable file; click a card's thumbnail (or its Download button) to load that exact file's URL straight into the manual downloader on the left
Recommended Models: a curated panel pulled from the SwarmUI docs' Image, Video, and Audio docs. Three columns, each model showing its architecture/scale/author and a variant dropdown (FP8, BF16, GGUF, NVFP4, LoRAs, etc.); pick a variant and hit Download to load it into the manual downloader, or Open to view the source page. Current top picks carry a Recommended badge. The panel and each column's overflow are independently collapsible, and remember their state.

[!NOTE] The Version and File dropdowns that appear when you paste a CivitAI link are core SwarmUI's, as of its 2026-08-17 Model Downloader update, not this extension's. The extension leaves them alone, and clears them when you replace the loaded model with a Hartsy link.
Folder browser: a collapsible tree of your existing model folders, shown in place of core's flat Folder dropdown and sitting in the same field row; expand and collapse branches, or create a subfolder with + New Folder without leaving the page

Destination preview: a live path showing exactly where the file will land, updating as you change type/folder/name. It is shown relative to your model root (Models/Lora/MyModel) rather than as an absolute path, so a shared instance does not print the server's filesystem layout to every user
Clipboard paste button for the URL field
Auth error messages: a download refused with a 401 or 403 shows the provider's own stated reason and which API key to set, using core SwarmUI's shared download error handling, plus a direct link to User Settings
Resumable downloads: download state is persisted server-side, so a SwarmUI restart mid-download leaves it paused (not lost); pause, resume, retry, and clear all work per-download from the Downloads list under the manual downloader
Server > ExtensionsSwarmUI/src/Extensions/SwarmUI-EnhancedDownloader/:
cd SwarmUI/src/Extensions/
git clone https://github.com/HartsyAI/SwarmUI-EnhancedDownloader.git
launch-*-dev scripts, which rebuild on every launch); the extension compiles automaticallyServer > ExtensionsNo extra setup is required. Every API key described below is optional, and every provider works anonymously out of the box.
Pasting a URL directly (CivitAI, Hugging Face, or any other direct-download link) works the same as it always has in SwarmUI. The browser on the right is a convenience on top, not a requirement.
Open the Recommended Models panel, pick a variant from a model's dropdown, and click Download to load it into the manual downloader, or Open to view its source page first. This list mirrors the current docs' recommendations, so it changes as SwarmUI's own recommendations do.
Downloads appear in the Downloads list under the manual downloader as soon as you start one. Each shows live progress: bytes transferred, percentage, and speed where the server reports a total size.

An in-progress download can be Canceled, which keeps the partial file so it can be resumed. A paused or errored one can be Resumed or Retryd from where it left off, or Cleared to delete the partial file.

Finished downloads turn green and can be Dismissed. They are hidden by default; tick Show completed to keep them in the list.
| Provider | Search | Filters | NSFW | Pagination | API Key |
|---|---|---|---|---|---|
| Hartsy | Yes | Architecture, tags, sort | No | Page-based | Optional |
| CivitAI | Yes | Type, base model, sort, period, tag, username | Yes (permission-gated) | Cursor (searches) / page (browse) | Optional |
| Hugging Face | Yes | Pipeline tag, library, sort, author | No | Cursor-based | Optional |

Hartsy is a curated model repository being built by the team behind this extension.
[!IMPORTANT] Hartsy.ai is not yet publicly released. While it's in this pre-release state, the catalog only contains base model repackages (SDXL, FLUX.2, Krea 2, HunyuanImage, and similar; see the screenshot above) rather than community finetunes or LoRAs. Browsing and downloading through this provider works today, but expect the catalog to grow substantially once the site is live.
Filters: architecture, tags, sort (newest/updated/title/downloads).
Notes:
hartsy.ai/models/<id> or hartsy.ai/Home?type=models&id=<id>) resolves through the Hartsy API automatically, the same way a CivitAI link does, so you don't need to use the browser for it to work
CivitAI is the largest community model repository.
Filters: type (Checkpoint, LoRA, VAE, ControlNet, etc.), base model, sort, time period, tag, username (also parseable straight out of @username in the search box).
Notes:
enhanced_downloader_nsfw permission (see Permissions) and toggling the NSFW checkbox. With both, requests route through civitai.red instead of civitai.com.safetensors; pasting a model or version URL auto-populates version and file dropdowns in the manual downloader
Hugging Face hosts a huge range of ML models.
Filters: pipeline tag (text-to-image, image-to-video, text-to-speech, etc.), library (diffusers, transformers, gguf, safetensors, etc.), sort, author.
Notes:
.safetensors, .gguf, .ckpt, etc.) and show file sizeEvery provider works anonymously. Adding a key raises rate limits and/or unlocks gated content:
[!WARNING] Never share your API keys. They're stored in your SwarmUI user data and are only ever sent to the corresponding provider's API.
NSFW results are off by default and only apply to CivitAI (Hartsy and Hugging Face don't expose an NSFW toggle at all). To see them:
enhanced_downloader_nsfw permission to your user/group under Server > Users & PermissionsThis extension talks to external hosts only when you actively search, browse, or download through it, never in the background, and never without you having initiated the action:
| Host | When | Why |
|---|---|---|
civitai.com / civitai.red | Searching/browsing CivitAI, loading a pasted CivitAI URL's metadata, downloading a CivitAI file | CivitAI's public API + CDN (civitai.red is used instead of civitai.com specifically for NSFW-enabled requests) |
huggingface.co | Searching/browsing Hugging Face, loading file listings/preview images, downloading a file | The Hugging Face Hub API |
hartsy.ai | Searching/browsing Hartsy, resolving a pasted Hartsy link, downloading a Hartsy file | The Hartsy API |
There's no way to disable the extension's network access short of disabling the extension itself (per SwarmUI's extension standards, everything above is a connection you triggered, not one made on your behalf).
Three permissions, all defaulting to POWERUSERS:
| Permission | Description |
|---|---|
enhanced_downloader | Base access: listing providers, download roots, and the recommended-models list |
enhanced_downloader_browse | Searching/browsing models across providers |
enhanced_downloader_nsfw | Including NSFW results (CivitAI only) |
Configure these under Server > Users & Permissions.
Starting, resuming, canceling, or clearing an actual download uses SwarmUI core's own Permissions.DownloadModels permission, not one of the three above. A user needs that core permission regardless of whether they can browse.
All endpoints are SwarmUI API.RegisterAPICall handlers (POST, JSON in/out), registered in WebAPI/EnhancedDownloaderAPI.cs.
| Endpoint | Permission | Params | Returns |
|---|---|---|---|
ListProviders | enhanced_downloader | none | {providers:[{id, displayName, supportsFilters, supportsNsfw}]} |
EnhancedDownloaderGetDownloadRoots | enhanced_downloader | none | {roots:{modelType: folderPath}} |
EnhancedDownloaderGetFeaturedModels | enhanced_downloader | none | {models:[{name, category, note, architecture, author, scale, isRecommended, downloads:[{label, url}]}]} |
| Endpoint | Params | Returns |
|---|---|---|
EnhancedDownloaderCivitaiSearch | query, page, limit, cursor, type, baseModel, sort, includeNsfw, period, username, tag, supportsGeneration, fromPlatform | {mode:"cursor"|"page", page, totalPages, totalItems, nextCursor, items} |
EnhancedDownloaderCivitaiFilterOptions | none | {types, baseModels} (live from CivitAI's /api/v1/enums) |
EnhancedDownloaderCivitaiTags | query, limit | {tags:[{name, modelCount}]} |
EnhancedDownloaderCivitaiImages | modelVersionId, limit, includeNsfw | {images:[{url, width, height, nsfwLevel, prompt, ...}]} |
EnhancedDownloaderCivitaiVersionFiles | modelVersionId | {files:[{fileName, downloadUrl, fileSize, format, precision, primary}]} |
EnhancedDownloaderCivitaiVersionCheck | modelVersionId | {requireAuth, canGenerate, earlyAccessEndsAt, hasApiKey, ...} |
All CivitAI endpoints require enhanced_downloader_browse.
| Endpoint | Params | Returns |
|---|---|---|
EnhancedDownloaderHuggingFaceSearch | query, limit, cursor, pipelineTag, library, sort, author | {mode:"cursor", nextCursor, totalItems, items} |
EnhancedDownloaderHuggingFaceFiles | modelId (required), limit | {files:[{fileName, downloadUrl, fileSize, quantType}], truncated} |
EnhancedDownloaderHuggingFaceImage | modelId (required) | {image:"data:image/...;base64,..."} |
All require enhanced_downloader_browse.
| Endpoint | Params | Returns |
|---|---|---|
EnhancedDownloaderHartsySearch | query, page, limit, architecture, sort, tags | {mode:"page", page, totalPages, totalItems, hasMore, items} |
EnhancedDownloaderHartsyFilterOptions | none | {architectures, tags, uploadSources, subscriptionTiers} |
EnhancedDownloaderHartsyModelDetails | modelId (required) | {title, description, architecture, author, image, downloads, tags, ...} (cached, no analytics recorded) |
EnhancedDownloaderHartsyDownload | modelId (required) | {downloadUrl, fileName, fileSize, hashSha256, torrent?} (records a download analytics event on Hartsy's side, not cached) |
EnhancedDownloaderHartsyVersions | modelId (required) | {familyId, title, groups:[{key, label, precisions, primary, variants}]}. One group per version; primary is the file the site generates with and variants are those same weights in other precisions |
All require enhanced_downloader_browse.
| Endpoint | Permission | Params | Returns |
|---|---|---|---|
EnhancedDownloaderListDownloads | enhanced_downloader | none | {downloads:[DownloadRecord]} |
EnhancedDownloaderStartDownload | Permissions.DownloadModels | url, type, name (all required), metadata, image | {download: DownloadRecord} |
EnhancedDownloaderResumeDownload | Permissions.DownloadModels | id (required) | {download: DownloadRecord} |
EnhancedDownloaderCancelDownload | Permissions.DownloadModels | id (required) | {download: DownloadRecord} |
EnhancedDownloaderClearDownload | Permissions.DownloadModels | id (required) | {success: true} |
A DownloadRecord looks like:
{
"id": "...", "url": "...", "type": "...", "name": "...", "extension": "...", "image": "...",
"totalBytes": 0, "downloadedBytes": 0, "perSecond": 0,
"state": "downloading | paused | errored | completed",
"error": "...", "note": "...", "createdAtMs": 0, "updatedAtMs": 0
}
Downloads are persisted per-user (LiteDB generic data) so a SwarmUI restart mid-download resumes as paused, not lost.
The failure message names the provider that refused it, quotes the reason that provider gave, and says whether an API key was sent. Add or check the relevant provider's API key in User Settings (see Configuration), then Retry from the Downloads list.
Server > ExtensionsHugging Face images are fetched lazily and aren't guaranteed for every repo; CivitAI images depend on what the model's author uploaded. Check the browser console for fetch errors if a specific thumbnail seems stuck.
Contributions welcome. Areas that would help most:
model_popover.js/getPopoverExtras exist but aren't currently attached to a visible trigger on the card)download_history.js is currently a placeholder)localStorage, but nothing displays them since the folder tree replaced core's dropdown)buildFolderBrowser() re-renders from coreModelMap, so a folder with no models in it yet never appears)MIT License. See LICENSE.
C#
50.1%
JavaScript
44.2%
CSS
5.7%
A SwarmUI extension that enhances the model download utility allowing you to browse from popular model sites
C#
3
63 commits
updated Sep 28, 2026

A full-featured model browser for SwarmUI's Utilities > Model Downloader tab. Search, preview, and download models from CivitAI, Hugging Face, and Hartsy without leaving SwarmUI or hand-typing a URL.
[!NOTE] This extension enhances SwarmUI's built-in Model Downloader. It does not replace it. The manual URL download workflow on the left is still core SwarmUI, just reorganized and given a few extra conveniences (a folder browser, a destination preview). The model browser on the right is new.

Three providers, one interface: switch between Hartsy, CivitAI, and Hugging Face with a dropdown; each keeps its own search/filter state
Filters: model type / architecture, base model, sort, tags, and (CivitAI only) NSFW, per provider. See Providers for exactly what each one supports
Page or cursor pagination, whichever the active provider's API uses
Model cards: thumbnail, title, creator, download count, and type/base-model badges, plus a version/format picker on cards that have more than one downloadable file; click a card's thumbnail (or its Download button) to load that exact file's URL straight into the manual downloader on the left
Recommended Models: a curated panel pulled from the SwarmUI docs' Image, Video, and Audio docs. Three columns, each model showing its architecture/scale/author and a variant dropdown (FP8, BF16, GGUF, NVFP4, LoRAs, etc.); pick a variant and hit Download to load it into the manual downloader, or Open to view the source page. Current top picks carry a Recommended badge. The panel and each column's overflow are independently collapsible, and remember their state.

[!NOTE] The Version and File dropdowns that appear when you paste a CivitAI link are core SwarmUI's, as of its 2026-08-17 Model Downloader update, not this extension's. The extension leaves them alone, and clears them when you replace the loaded model with a Hartsy link.
Folder browser: a collapsible tree of your existing model folders, shown in place of core's flat Folder dropdown and sitting in the same field row; expand and collapse branches, or create a subfolder with + New Folder without leaving the page

Destination preview: a live path showing exactly where the file will land, updating as you change type/folder/name. It is shown relative to your model root (Models/Lora/MyModel) rather than as an absolute path, so a shared instance does not print the server's filesystem layout to every user
Clipboard paste button for the URL field
Auth error messages: a download refused with a 401 or 403 shows the provider's own stated reason and which API key to set, using core SwarmUI's shared download error handling, plus a direct link to User Settings
Resumable downloads: download state is persisted server-side, so a SwarmUI restart mid-download leaves it paused (not lost); pause, resume, retry, and clear all work per-download from the Downloads list under the manual downloader
Server > ExtensionsSwarmUI/src/Extensions/SwarmUI-EnhancedDownloader/:
cd SwarmUI/src/Extensions/
git clone https://github.com/HartsyAI/SwarmUI-EnhancedDownloader.git
launch-*-dev scripts, which rebuild on every launch); the extension compiles automaticallyServer > ExtensionsNo extra setup is required. Every API key described below is optional, and every provider works anonymously out of the box.
Pasting a URL directly (CivitAI, Hugging Face, or any other direct-download link) works the same as it always has in SwarmUI. The browser on the right is a convenience on top, not a requirement.
Open the Recommended Models panel, pick a variant from a model's dropdown, and click Download to load it into the manual downloader, or Open to view its source page first. This list mirrors the current docs' recommendations, so it changes as SwarmUI's own recommendations do.
Downloads appear in the Downloads list under the manual downloader as soon as you start one. Each shows live progress: bytes transferred, percentage, and speed where the server reports a total size.

An in-progress download can be Canceled, which keeps the partial file so it can be resumed. A paused or errored one can be Resumed or Retryd from where it left off, or Cleared to delete the partial file.

Finished downloads turn green and can be Dismissed. They are hidden by default; tick Show completed to keep them in the list.
| Provider | Search | Filters | NSFW | Pagination | API Key |
|---|---|---|---|---|---|
| Hartsy | Yes | Architecture, tags, sort | No | Page-based | Optional |
| CivitAI | Yes | Type, base model, sort, period, tag, username | Yes (permission-gated) | Cursor (searches) / page (browse) | Optional |
| Hugging Face | Yes | Pipeline tag, library, sort, author | No | Cursor-based | Optional |

Hartsy is a curated model repository being built by the team behind this extension.
[!IMPORTANT] Hartsy.ai is not yet publicly released. While it's in this pre-release state, the catalog only contains base model repackages (SDXL, FLUX.2, Krea 2, HunyuanImage, and similar; see the screenshot above) rather than community finetunes or LoRAs. Browsing and downloading through this provider works today, but expect the catalog to grow substantially once the site is live.
Filters: architecture, tags, sort (newest/updated/title/downloads).
Notes:
hartsy.ai/models/<id> or hartsy.ai/Home?type=models&id=<id>) resolves through the Hartsy API automatically, the same way a CivitAI link does, so you don't need to use the browser for it to work
CivitAI is the largest community model repository.
Filters: type (Checkpoint, LoRA, VAE, ControlNet, etc.), base model, sort, time period, tag, username (also parseable straight out of @username in the search box).
Notes:
enhanced_downloader_nsfw permission (see Permissions) and toggling the NSFW checkbox. With both, requests route through civitai.red instead of civitai.com.safetensors; pasting a model or version URL auto-populates version and file dropdowns in the manual downloader
Hugging Face hosts a huge range of ML models.
Filters: pipeline tag (text-to-image, image-to-video, text-to-speech, etc.), library (diffusers, transformers, gguf, safetensors, etc.), sort, author.
Notes:
.safetensors, .gguf, .ckpt, etc.) and show file sizeEvery provider works anonymously. Adding a key raises rate limits and/or unlocks gated content:
[!WARNING] Never share your API keys. They're stored in your SwarmUI user data and are only ever sent to the corresponding provider's API.
NSFW results are off by default and only apply to CivitAI (Hartsy and Hugging Face don't expose an NSFW toggle at all). To see them:
enhanced_downloader_nsfw permission to your user/group under Server > Users & PermissionsThis extension talks to external hosts only when you actively search, browse, or download through it, never in the background, and never without you having initiated the action:
| Host | When | Why |
|---|---|---|
civitai.com / civitai.red | Searching/browsing CivitAI, loading a pasted CivitAI URL's metadata, downloading a CivitAI file | CivitAI's public API + CDN (civitai.red is used instead of civitai.com specifically for NSFW-enabled requests) |
huggingface.co | Searching/browsing Hugging Face, loading file listings/preview images, downloading a file | The Hugging Face Hub API |
hartsy.ai | Searching/browsing Hartsy, resolving a pasted Hartsy link, downloading a Hartsy file | The Hartsy API |
There's no way to disable the extension's network access short of disabling the extension itself (per SwarmUI's extension standards, everything above is a connection you triggered, not one made on your behalf).
Three permissions, all defaulting to POWERUSERS:
| Permission | Description |
|---|---|
enhanced_downloader | Base access: listing providers, download roots, and the recommended-models list |
enhanced_downloader_browse | Searching/browsing models across providers |
enhanced_downloader_nsfw | Including NSFW results (CivitAI only) |
Configure these under Server > Users & Permissions.
Starting, resuming, canceling, or clearing an actual download uses SwarmUI core's own Permissions.DownloadModels permission, not one of the three above. A user needs that core permission regardless of whether they can browse.
All endpoints are SwarmUI API.RegisterAPICall handlers (POST, JSON in/out), registered in WebAPI/EnhancedDownloaderAPI.cs.
| Endpoint | Permission | Params | Returns |
|---|---|---|---|
ListProviders | enhanced_downloader | none | {providers:[{id, displayName, supportsFilters, supportsNsfw}]} |
EnhancedDownloaderGetDownloadRoots | enhanced_downloader | none | {roots:{modelType: folderPath}} |
EnhancedDownloaderGetFeaturedModels | enhanced_downloader | none | {models:[{name, category, note, architecture, author, scale, isRecommended, downloads:[{label, url}]}]} |
| Endpoint | Params | Returns |
|---|---|---|
EnhancedDownloaderCivitaiSearch | query, page, limit, cursor, type, baseModel, sort, includeNsfw, period, username, tag, supportsGeneration, fromPlatform | {mode:"cursor"|"page", page, totalPages, totalItems, nextCursor, items} |
EnhancedDownloaderCivitaiFilterOptions | none | {types, baseModels} (live from CivitAI's /api/v1/enums) |
EnhancedDownloaderCivitaiTags | query, limit | {tags:[{name, modelCount}]} |
EnhancedDownloaderCivitaiImages | modelVersionId, limit, includeNsfw | {images:[{url, width, height, nsfwLevel, prompt, ...}]} |
EnhancedDownloaderCivitaiVersionFiles | modelVersionId | {files:[{fileName, downloadUrl, fileSize, format, precision, primary}]} |
EnhancedDownloaderCivitaiVersionCheck | modelVersionId | {requireAuth, canGenerate, earlyAccessEndsAt, hasApiKey, ...} |
All CivitAI endpoints require enhanced_downloader_browse.
| Endpoint | Params | Returns |
|---|---|---|
EnhancedDownloaderHuggingFaceSearch | query, limit, cursor, pipelineTag, library, sort, author | {mode:"cursor", nextCursor, totalItems, items} |
EnhancedDownloaderHuggingFaceFiles | modelId (required), limit | {files:[{fileName, downloadUrl, fileSize, quantType}], truncated} |
EnhancedDownloaderHuggingFaceImage | modelId (required) | {image:"data:image/...;base64,..."} |
All require enhanced_downloader_browse.
| Endpoint | Params | Returns |
|---|---|---|
EnhancedDownloaderHartsySearch | query, page, limit, architecture, sort, tags | {mode:"page", page, totalPages, totalItems, hasMore, items} |
EnhancedDownloaderHartsyFilterOptions | none | {architectures, tags, uploadSources, subscriptionTiers} |
EnhancedDownloaderHartsyModelDetails | modelId (required) | {title, description, architecture, author, image, downloads, tags, ...} (cached, no analytics recorded) |
EnhancedDownloaderHartsyDownload | modelId (required) | {downloadUrl, fileName, fileSize, hashSha256, torrent?} (records a download analytics event on Hartsy's side, not cached) |
EnhancedDownloaderHartsyVersions | modelId (required) | {familyId, title, groups:[{key, label, precisions, primary, variants}]}. One group per version; primary is the file the site generates with and variants are those same weights in other precisions |
All require enhanced_downloader_browse.
| Endpoint | Permission | Params | Returns |
|---|---|---|---|
EnhancedDownloaderListDownloads | enhanced_downloader | none | {downloads:[DownloadRecord]} |
EnhancedDownloaderStartDownload | Permissions.DownloadModels | url, type, name (all required), metadata, image | {download: DownloadRecord} |
EnhancedDownloaderResumeDownload | Permissions.DownloadModels | id (required) | {download: DownloadRecord} |
EnhancedDownloaderCancelDownload | Permissions.DownloadModels | id (required) | {download: DownloadRecord} |
EnhancedDownloaderClearDownload | Permissions.DownloadModels | id (required) | {success: true} |
A DownloadRecord looks like:
{
"id": "...", "url": "...", "type": "...", "name": "...", "extension": "...", "image": "...",
"totalBytes": 0, "downloadedBytes": 0, "perSecond": 0,
"state": "downloading | paused | errored | completed",
"error": "...", "note": "...", "createdAtMs": 0, "updatedAtMs": 0
}
Downloads are persisted per-user (LiteDB generic data) so a SwarmUI restart mid-download resumes as paused, not lost.
The failure message names the provider that refused it, quotes the reason that provider gave, and says whether an API key was sent. Add or check the relevant provider's API key in User Settings (see Configuration), then Retry from the Downloads list.
Server > ExtensionsHugging Face images are fetched lazily and aren't guaranteed for every repo; CivitAI images depend on what the model's author uploaded. Check the browser console for fetch errors if a specific thumbnail seems stuck.
Contributions welcome. Areas that would help most:
model_popover.js/getPopoverExtras exist but aren't currently attached to a visible trigger on the card)download_history.js is currently a placeholder)localStorage, but nothing displays them since the folder tree replaced core's dropdown)buildFolderBrowser() re-renders from coreModelMap, so a folder with no models in it yet never appears)MIT License. See LICENSE.
C#
50.1%
JavaScript
44.2%
CSS
5.7%