The reference for consumers of the published files.
All urls are relative to https://containerbase.github.io/tool-versions/.
index.json lists the published formats.
Pin a major version of the format and read the root index only to warn when it is deprecated.
{
"$schema": "https://containerbase.github.io/tool-versions/formats.schema.json",
"defaultDistro": "noble",
"formats": [{ "version": 1, "path": "v1/", "status": "current" }]
}defaultDistro: the codename of the Ubuntu release the default containerbase image is built from, from@containerbase/base. TheminVersionof the tools refers to it.formats[].status:current,previewordeprecated.formats[].removalDate: when a deprecated format is removed, only for those.- Schema:
formats.schema.json.
release.json has the release of the deployed data and when it was built.
{
"$schema": "https://containerbase.github.io/tool-versions/release.schema.json",
"version": "1.7.22",
"buildTime": "2026-10-28T03:00:00.000Z"
}version: the release the data belongs to. A build which makes no release keeps the version of the latest release.buildTime: when the build of the data started, theupdatedAtofv1/index.json. It changes with every build, also without a release.- The release archive has the same file as the site at the time of the release.
- A reader with embedded data can fetch only this file and compare the
buildTimeto decide whether the online data is newer. - It is outside the format folders and the integrity chain, it doesn't change the data files.
- Schema:
release.schema.json.
Everything else is in the folder of a format, v1/ for now.
The paths are relative to the folder of the format, like v1/.
| File | Content | Read by | Schema |
|---|---|---|---|
index.json |
all tools, with the file names and integrity of their files | clients, to find the other files | index.schema.json |
<tool>.json |
the versions of a tool, without their files | Renovate, version resolution | tool.schema.json |
<tool>/<version>.json |
the files of one version, only for tools with files | the install | version.schema.json |
<tool>.integrity.json |
the integrity of each <tool>/<version>.json, same condition |
the install | integrity.schema.json |
- Every file has its schema url as the first property,
$schema. - The file name of a version is the raw version, so
java/25.0.4+101.0.LTS.jsonhas a literal+. Request it url encoded (%2B). - Versions with characters other than
[0-9A-Za-z.+_-]are left out. - Tools with a
type(installed by a package manager) have no files.
Optional fields are omitted when unknown.
| Field | Type | Meaning |
|---|---|---|
tool |
string | the tool name |
type |
dotnet, gem, npm, pip |
the package manager which installs the tool, from @containerbase/base |
sourceUrl |
url | where the source code lives, for changelogs |
homepage |
url | the homepage |
lts |
true |
the tool has LTS release streams, like node and java, only present when true |
latest |
string | the version upstream calls latest, only for sources with one and only when it is listed, see below |
minVersion |
string | the oldest supported version on the defaultDistro, in the versioning of the tool |
distroMinVersion |
map of codename to version | the oldest version on a distro, only where it differs from minVersion. Any codename can be a key |
minCb |
list of version and cb |
the oldest containerbase version which can install a version and the ones above it, see below |
source |
object | deprecated build information, don't use it, see below |
updatedAt |
UTC time | when the build ran |
versions |
list | the versions, newest first, prereleases included |
versions[].version |
string | the exact install-tool version |
versions[].prerelease, lts |
true |
only present when true |
versions[].deprecated |
true |
npm deprecated, all pypi files yanked, removed from rubygems or nuget.exe not blessed, see below |
versions[].releaseTimestamp |
UTC time | when the version was released, for Renovate's minimumReleaseAge |
versions[].constraints |
map of tool to constraint | the runtime the version needs, keyed by the parent tool, see below |
versions[].archs |
list of amd64, arm64 |
the archs with a file of the version, sorted, only in <tool>.json, see below |
versions[].distros |
list of codenames | the distros with a file of the version, sorted, only in <tool>.json, see below |
files |
list | the files of a version, sorted by name, only in the per-version files |
files[].name |
string | the file name |
files[].url |
https url | where to download it |
files[].checksum |
string | sha256:, sha512: or sha1: and the lowercase hex digest |
files[].arch |
amd64, arm64 |
the architecture, omitted for files which work on every one |
files[].distro |
string | the distro codename, for distro specific files |
source (datasource, packageName, versioning) is deprecated.
It describes how the build fetches the versions, readers must not rely on it.
It is removed with the next format major (#146).
latest is the version to resolve latest to, when it is present.
It is only set when the version is listed. When the source has no listed one, like a new one which waits for the minimum release age, the previous one is kept while it is listed:
- Tools from npm have the version of the
latestdist-tag. gradlehas theversionofservices.gradle.org/versions/current.- Tools from GitHub releases and
rusthave the version of the GitHub "latest release", also when it is a prerelease.nodeandmavenhave the one ofcontainerbase/node-prebuildandcontainerbase/maven-prebuild. android-sdk-cmdline-toolshas the version of thecmdline-tools;latestpackage, written like the other versions.poetryhas the newest stable, not deprecated release which satisfies thepoetryrequirement in therequires_distof the latestpoetry-plugin-pypi-mirrorrelease.
versions[].deprecated is only present when true. Readers skip deprecated versions when they resolve latest or a partial version:
- Tools from npm have the versions the registry deprecated.
- Tools from PyPI have the releases whose files are all yanked.
- Tools from RubyGems have the versions removed from the registry.
nugethas thenuget.exereleases of the stageReleased, which aren'tReleasedAndBlessed.
versions[].constraints is only present when the registry or the release has a constraint for the version:
- Constraints of a registry don't change once published, the registry is only read for versions without one. The elixir ones are derived on each build, so a fixed rule replaces published ones.
- It is keyed by the parent tool, like
node,pythonorruby, and the value is the raw constraint in the syntax of the registry. Evaluate it with the versioning of the parent tool, like Renovate does. elixirhas theerlangconstraint>=<min> <<max+1>of the OTP majors of theelixir-otp-<major>.zipassets of the release, like>=25 <28. Releases before 1.14 have no such assets, they take the range of the compatibility table. Releases which don't support OTP 24 (before 1.11.4) take>=24 <25: it's the oldest erlang containerbase can install, the newest one surely breaks them.- Tools from npm have
engines.nodeas thenodeconstraint, notdevEngines. - Tools from PyPI have
requires_pythonas thepythonconstraint. It is the first one of the files which are not yanked. - Tools from RubyGems have
required_ruby_versionas therubyconstraint, unless it accepts any ruby (>= 0).
minCb is only present for tools with releases which an older containerbase can't install, like a new version scheme.
Each entry is a version and the oldest containerbase version cb which can install it:
- The range of an entry starts at its
version: it applies to that version and to every version listed above it, asversionsis sorted newest first. Readers only need the list positions, not the versioning of the tool. - Readers skip the versions of an entry whose
cbis above their containerbase version.devbuilds of containerbase don't filter. - Readers which don't know the field ignore it.
versions[].archs and versions[].distros list the files[].arch and files[].distro of the version, so a version can be resolved without its files:
archsis omitted for tools with atype, which have no files, and for versions whose files all work on every architecture.distrosis omitted for tools with atypeand for versions without distro specific files.- To pick a version for a host, check that it is listed (so at least
minVersion), at least thedistroMinVersionof the host distro, and has the host arch and distro inarchsanddistros, or the field is missing. This skips a release whosearm64build is still missing, for example.
Which versions are listed:
- Only versions with an
amd64file or a file for any architecture, unless the tool has atype. - Not the versions below
minVersion. - Not the files of a distro for versions below its
distroMinVersion.
v1/python.json, the files are in v1/python/3.14.8.json:
{
"$schema": "https://containerbase.github.io/tool-versions/v1/tool.schema.json",
"tool": "python",
"sourceUrl": "https://github.com/python/cpython",
"homepage": "https://www.python.org",
"minVersion": "2.7.18",
"source": {
"datasource": "github-releases",
"packageName": "containerbase/python-prebuild",
"versioning": "python"
},
"updatedAt": "2026-10-08T03:00:00.000Z",
"versions": [
{
"version": "3.14.8",
"releaseTimestamp": "2026-10-02T01:30:20.000Z",
"archs": ["amd64"],
"distros": ["jammy"]
}
]
}v1/npm.json, a tool with constraints:
{
"$schema": "https://containerbase.github.io/tool-versions/v1/tool.schema.json",
"tool": "npm",
"type": "npm",
"source": { "datasource": "npm", "packageName": "npm", "versioning": "npm" },
"updatedAt": "2026-10-08T03:00:00.000Z",
"versions": [
{
"version": "12.0.0",
"releaseTimestamp": "2026-09-30T10:00:00.000Z",
"constraints": { "node": "^20.17.0 || >=22.9.0" }
}
]
}v1/python/3.14.8.json:
{
"$schema": "https://containerbase.github.io/tool-versions/v1/version.schema.json",
"tool": "python",
"version": "3.14.8",
"files": [
{
"name": "python-3.14.8-jammy-x86_64.tar.xz",
"url": "https://github.com/containerbase/python-prebuild/releases/download/3.14.8/python-3.14.8-jammy-x86_64.tar.xz",
"checksum": "sha512:6976…",
"arch": "amd64",
"distro": "jammy"
}
]
}The client files are also attached to each GitHub release as tool-versions-<version>.tar.xz, with tool-versions-<version>.tar.xz.sha512.
- The archive has the root
index.json,release.json, their schemas and thev1/folder, with the same paths as on the site. - The next build starts from it: the
filesof a version are in its<tool>/<version>.json. - The
.sha512file has the lowercase hex digest of the archive, like the ones of the containerbase prebuilds. - It is meant for embedding the data, like in the containerbase image.
- The site stays the primary source, it is always the latest data.
How the releases are made is in the build docs.
- A breaking change is published in a new folder, like
v2/, and listed in the root index. - Breaking means renaming or removing a field, or changing its meaning.
- The old folder keeps being published for a while, as
deprecatedwith aremovalDate. - Adding optional fields is not breaking.
The client files form a hash chain:
index.jsonhas the integrity of each<tool>.jsonand<tool>.integrity.json.<tool>.integrity.jsonhas the integrity of each<tool>/<version>.json.- The digests are not in
<tool>.json, so the version list stays small.
An integrity is the SRI-style sha256 digest of the exact published bytes, like npm's: sha256-<base64>.
It includes the $schema.
On a mismatch, fetch index.json again and retry once.
A mismatch can come from corruption, truncation, or files of different deploys mixed by a stale cache.
The chain doesn't prove who published the files, as index.json changes with every build.
Trust comes from HTTPS and GitHub Pages.