Skip to content

Registries

BatleHub proxies, caches, and privately hosts 21 registry types — from language package managers to OS package repositories, editor extension marketplaces, and generic file mirrors.

Every registry type can run in one of three modes, set per registry in the config:

  • proxy — a pure read-through cache in front of an upstream. The first request is fetched from upstream and stored; every later request is served from cache.
  • local — a fully private registry. Nothing is fetched from upstream; you publish and serve your own artifacts.
  • hybrid — local artifacts win, and anything not published locally falls through to the upstream proxy.

Five types are proxy-only (no private publish model): GitHub, Forgejo, GitLab (they host source/releases upstream) and JetBrains IDE archives + Generic file mirrors (path-only caches).

The registries

Source hosting

RegistrytypeWhat it proxiesModesPublishDefault upstream
GitHubgithubReleases, assets, tarballs, raw filesproxy-onlyapi.github.com
Forgejo / GiteaforgejoReleases, assets, archives, raw (/api/v1)proxy-onlycodeberg.org
GitLabgitlabReleases, link assets, archives (/api/v4)proxy-onlygitlab.com

Language package managers

RegistrytypeWhat it proxiesModesPublishDefault upstream
npmnpmPackument + tarballsproxy · local · hybridregistry.npmjs.org
CargocargoSparse index + .crateproxy · local · hybridcrates.io
Go ModulesgoproxyGOPROXY (.info/.mod/.zip)proxy · local · hybridproxy.golang.org
MavenmavenMetadata XML + JAR/POMproxy · local · hybridrepo1.maven.org
PyPIpypiSimple API (PEP 503/691) + wheelsproxy · local · hybridpypi.org
Condacondarepodata.json + .conda/.tar.bz2proxy · local · hybridconda.anaconda.org
Composer (PHP)composerPackagist v2 (p2 metadata + dist)proxy · local · hybridrepo.packagist.org
RubyGemsrubygemsGems + versions + info APIproxy · local · hybridrubygems.org
NuGet (.NET)nugetv3 index + flat + .nupkgproxy · local · hybridapi.nuget.org
TerraformterraformProviders + modules (v1 API)proxy · local · hybridregistry.terraform.io

Editor extensions

RegistrytypeWhat it proxiesModesPublishDefault upstream
OpenVSXopenvsxExtension VSIXproxy · local · hybridopen-vsx.org
VS Code Marketplacevscode-marketplaceExtension VSIX (MS Gallery)proxy · local · hybridmarketplace.visualstudio.com
JetBrains Marketplacejetbrains-marketplacePlugin API + downloadsproxy · local · hybridplugins.jetbrains.com

OS / system packages path-addressed

RegistrytypeWhat it proxiesModesPublishDefault upstream
Debian / APTdebPackages/Release + .debproxy · local · hybridnone — set upstreams
RPM / YUM / DNFrpmrepodata/ + .rpmproxy · local · hybridnone — set upstreams
Pacman / Archpacman<repo>.db + .pkg.tar.zstproxy · local · hybridnone — set upstreams

Binaries & mirrors path-addressed

RegistrytypeWhat it proxiesModesPublishDefault upstream
JetBrains IDEsjetbrainsIDE installer archivesproxy-onlydownload.jetbrains.com
Generic mirrorgenericAny HTTP file treeproxy-onlynone — set upstreams + path_allow

Feature matrix

Every registry and how its capabilities map across BatleHub's features. The path-addressed types (Deb, RPM, Pacman, JetBrains IDEs, Generic) have no per-package version model, so the structural axes (version listing, source archive, binary, age gate, warming, search) show . They still get registry-level RBAC and multi-upstream fanout, and Deb/RPM/Pacman support signed private hosting. Forgejo and GitLab mirror GitHub's behaviour.

Legend: Ver. version listing · Src source archive · Bin binary/extension asset · Pub private publish · Fan multi-upstream fanout · Age release age gate · Warm cache warming (version enumeration) · Search Package Explorer upstream search. ✓ supported · not applicable · ⚠ partial.

RegistryVer.SrcBinPubFanAgeRBACWarmSearch
GitHub
Forgejo / Gitea
GitLab
npm
Cargo
Go Modules
Maven
PyPI
Conda✓ ¹⚠ ²✓ ¹
Composer
RubyGems
NuGet
Terraform
OpenVSX
VS Code Marketplace
JetBrains Marketplace
Debian / APT ³
RPM / YUM / DNF ³
Pacman / Arch ³
JetBrains IDEs ³
Generic ³

¹ Conda has no dedicated per-package version listing API. BatleHub synthesises one by scanning repodata.json across noarch, linux-64, osx-64, osx-arm64, and win-64; results are the union of versions found on all available platforms.

² Conda timestamps come from the timestamp field in repodata.json (ms since epoch). Most packages carry it; packages without one skip the gate unless you set deny_missing_timestamp = true on the rule.

³ Path-addressed type: artifacts are fetched by file path with no per-package version model, so the structural axes show . These types don't enumerate versions but can pre-warm specific files via cache.warm_paths, and are gated with a mandatory path_allow allowlist. Deb/RPM/Pacman additionally support signed private hosting (local/hybrid); JetBrains IDE archives and Generic are proxy-only.

Package Explorer upstream ("Not Yet Proxied") search: Go uses pkg.go.dev; PyPI is exact-name lookup; Terraform combines module search with namespace/exact provider lookup. The release proxies (GitHub/Forgejo/GitLab), VS Code Marketplace, Conda, and the path-addressed types have no upstream search API — see the Package Explorer guide.

READMEs

What a package says about itself, per version. Whether a registry has one at all is a property of its protocol, not a preference: the text either travels in a document the proxy already fetches to resolve a version, or it sits inside the artifact — and that decides whether the package page can show it for a version this instance holds no bytes for.

Held nowhere here is the column worth reading before you go looking for a gap: versions + README means the package page answers in full for a package nothing here has ever pulled; versions only means it lists the versions and says the README arrives when one is first downloaded; neither means the page answers from what this instance holds and nothing else.

Fetchable is whether the page offers a Fetch this version button on those upstream-only rows. no is not a limitation of the button but of the coordinate: a Maven version is a set of files, a Terraform provider is addressed by OS and architecture as well as version, a PyPI version is an sdist plus one wheel per interpreter and platform, and a conda artifact carries a channel platform and a build string — so "fetch this version" has no single meaning for any of them. The page says which rather than showing a disabled button — see fetching from the console.

RegistryREADME sourcePer versionHeld nowhere hereFetchable
githubthe README is one of the repository files this proxy already serves by path, under raw/{ref}/, so a second URL for it would be a second answer to a solved questionneitherno
forgejothe README is one of the repository files this proxy already serves by path, under raw/{ref}/, so a second URL for it would be a second answer to a solved questionneitherno
gitlabthe README is one of the repository files this proxy already serves by path, under raw/{ref}/, so a second URL for it would be a second answer to a solved questionneitherno
cargoa file inside the artifactyesversions onlyyes
npmthe metadata document, else the artifactyesversions + READMEyes
openvsxa URL in the metadata, read separatelyyesversions + READMEyes
goproxya file inside the artifactyesversions onlyyes
pypithe metadata document, else the artifactyesversions + READMEno
condaa file inside the artifactyesversions onlyno
composera file inside the artifactyesversions onlyyes
vscode-marketplacea URL in the metadata, read separatelyyesversions + READMEyes
maventhe POM carries <description>, which is a sentence rather than a document; putting one where a reader expects the other makes every package look thinly documentedversions onlyno
terraforma file inside the artifactyesversions onlyno
rubygemsa file inside the artifactyesversions onlyyes
nugeta file inside the artifactyesversions onlyyes
debpath-addressed: there is no package identity to hang a README onneitherno
rpmpath-addressed: there is no package identity to hang a README onneitherno
pacmanpath-addressed: there is no package identity to hang a README onneitherno
jetbrainspath-addressed: there is no package identity to hang a README onneitherno
jetbrains-marketplacethe metadata document, already fetchedyesversions + READMEyes
genericpath-addressed: there is no package identity to hang a README onneitherno

Configured per registry with [registries.readme] and [registries.upstream_detail]. Both are on by default, and the second one makes an outbound request the first time somebody opens a package page for something this instance holds nothing of — see what leaves this instance.

Two settings shape what else the page can do: remote_images = "proxy" renders a README's images through this server rather than charting them, and console_fetch (on by default) is the Fetch this version button. Prose search across stored READMEs is instance-wide and off by default — [search] readmes.

See also

Released under the Apache 2.0 License. Made with ❤️ and too much ☕.