Community-maintained catalog of OS installation ISOs - One source of truth for recovery and installation media.
A simple JSON catalog of official download links for operating system ISOs. Use it in your desktop apps, mobile apps, or web tools to give users easy access to recovery media.
https://raw.githubusercontent.com/barrersoftware/iso-catalog/main/catalog.json
The catalog is always up-to-date. Your app fetches it at runtime - no rebuilds needed when new ISOs are added.
- Windows: 11, 10, Server 2025
- Ubuntu: 24.04 LTS (Desktop/Server), 22.04 LTS
- Fedora: 41 (Workstation/Server)
- Debian: 12 (Bookworm)
- More coming: Community PRs welcome!
import org.json.JSONObject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
data class IsoTemplate(
val name: String,
val downloadUrl: String,
val sizeBytes: Long,
val category: String
)
suspend fun fetchIsoCatalog(): List<IsoTemplate> = withContext(Dispatchers.IO) {
val url = "https://raw.githubusercontent.com/barrersoftware/iso-catalog/main/catalog.json"
val json = java.net.URL(url).readText()
val catalog = JSONObject(json)
val templates = mutableListOf<IsoTemplate>()
val categories = catalog.getJSONArray("categories")
for (i in 0 until categories.length()) {
val category = categories.getJSONObject(i)
val categoryName = category.getString("name")
val categoryTemplates = category.getJSONArray("templates")
for (j in 0 until categoryTemplates.length()) {
val template = categoryTemplates.getJSONObject(j)
templates.add(IsoTemplate(
name = template.getString("name"),
downloadUrl = template.getString("downloadUrl"),
sizeBytes = template.getLong("sizeBytes"),
category = categoryName
))
}
}
templates
}using System.Text.Json;
public record IsoTemplate(
string Name,
string DownloadUrl,
long SizeBytes,
string Category
);
public static async Task<List<IsoTemplate>> FetchIsoCatalog()
{
const string url = "https://raw.githubusercontent.com/barrersoftware/iso-catalog/main/catalog.json";
using var client = new HttpClient();
var json = await client.GetStringAsync(url);
var catalog = JsonDocument.Parse(json);
var templates = new List<IsoTemplate>();
foreach (var category in catalog.RootElement.GetProperty("categories").EnumerateArray())
{
var categoryName = category.GetProperty("name").GetString();
foreach (var template in category.GetProperty("templates").EnumerateArray())
{
templates.Add(new IsoTemplate(
Name: template.GetProperty("name").GetString()!,
DownloadUrl: template.GetProperty("downloadUrl").GetString()!,
SizeBytes: template.GetProperty("sizeBytes").GetInt64(),
Category: categoryName!
));
}
}
return templates;
}import requests
def fetch_iso_catalog():
url = "https://raw.githubusercontent.com/barrersoftware/iso-catalog/main/catalog.json"
response = requests.get(url)
catalog = response.json()
templates = []
for category in catalog["categories"]:
category_name = category["name"]
for template in category["templates"]:
templates.append({
"name": template["name"],
"download_url": template["downloadUrl"],
"size_bytes": template["sizeBytes"],
"category": category_name
})
return templatesasync function fetchIsoCatalog() {
const url = "https://raw.githubusercontent.com/barrersoftware/iso-catalog/main/catalog.json";
const response = await fetch(url);
const catalog = await response.json();
const templates = [];
for (const category of catalog.categories) {
const categoryName = category.name;
for (const template of category.templates) {
templates.push({
name: template.name,
downloadUrl: template.downloadUrl,
sizeBytes: template.sizeBytes,
category: categoryName
});
}
}
return templates;
}Always bundle a copy of the catalog with your app as fallback:
val json = try {
// Try live catalog
fetchFromGitHub()
} catch (e: Exception) {
// Fall back to bundled version
loadBundledCatalog()
}Cache the catalog for 24 hours to reduce requests:
private static DateTime lastFetch = DateTime.MinValue;
private static List<IsoTemplate>? cachedCatalog;
public static async Task<List<IsoTemplate>> GetCatalog()
{
if (DateTime.Now - lastFetch < TimeSpan.FromHours(24) && cachedCatalog != null)
return cachedCatalog;
cachedCatalog = await FetchIsoCatalog();
lastFetch = DateTime.Now;
return cachedCatalog;
}Want to add an ISO? See CONTRIBUTING.md
Requirements:
- Must be official download from vendor
- Include SHA256 checksum
- Provide recommended system specs
- Keep version up to date
- ISOForge - Android USB bootable creator
- CleanVM - Desktop VM management tool
Using this in your project? Send a PR to add it here!
Public domain (CC0) - Use it however you want. The catalog contains only publicly available download links.
Barrer Software 🏴☠️
Community contributions welcome!