App Manifest Schema
Every application listed on Dolphin Depot has a manifest.json file in the DolphinDepot/registry repository. This reference describes all available fields, types, and constraints.
Overview
A full manifest.json example covering every required field and the most common optional ones. Each field is documented in its own section below; no additional properties are allowed at the top level.
{
"name": "CleanRip",
"author": "emu_kidid",
"description_short": "Disc Backup Tool for GC/Wii Discs",
"description_long": "A tool to backup your GameCube/Wii discs via IOS58. Creates 1:1 backups for archival purposes without any requirements for custom IOS (cIOS). Supports USB 2.0, NTFS, exFAT and Front SD.",
"category": "utilities",
"platforms": ["gamecube", "panasonic_q"],
"peripherals": ["controller", "sd_gecko", "sd2sp2", "m2loader", "mmce"],
"license": {
"spdx": "GPL-2.0-only",
"url": "https://github.com/emukidid/cleanrip/blob/master/LICENSE"
},
"source": {
"type": "github_release",
"repository": "emukidid/cleanrip",
"asset_pattern": "CleanRip-*-gc.zip"
},
"treatments": [
{
"treatment": "archive.extract",
"arguments": ["CleanRip-*-gc.zip", "."]
},
{
"treatment": "contents.move",
"arguments": ["cleanrip-gc.dol", "apps/cleanrip/default.dol"]
},
{
"treatment": "registry.copy",
"arguments": ["opening.bnr", "apps/cleanrip/opening.bnr"]
}
]
}Name
name required type string min length 1 Display name of the homebrew application as shown in the catalog.
Author
author required type string min length 1 Name of the application author or primary maintainer.
Short description
description_short required type string min length 1 max length 160 Brief one-line summary of the application. Displayed in catalog listings.
Long description
description_long optional type string max length 500 Extended description of the application. Displayed on the application detail page.
Category
category required type string Category the application belongs to. Must be one of: games, emulators, utilities, demos, media.
Platforms
platforms optional type string[] List of compatible hardware platforms. If omitted, no platform compatibility is specified. Each entry must be one of: gamecube, panasonic_q, triforce, tdev, gdev, npdp_reader, nr_reader, wii_nintendont, wii_swiss, dolphin.
Peripherals
peripherals optional type string[] List of supported or required peripherals and accessories. Each entry must be one of: controller, keyboard, gb_player, gba_link_cable, microphone, memory_card, disc, action_pad, dk_bongos, steering_wheel, sd_gecko, sd2sp2, m2loader, mmce, bba, modem, eth2gc, gcloader, cubeode, flippydrive, picoboot, usb_gecko.
License
license required type object Licensing information for the application. The catalog uses it to display a license badge and link to the full license text.
Properties
| Name | Type | Description | Required |
|---|---|---|---|
| spdx | string | SPDX license identifier or expression. Examples: MIT, GPL-2.0-only, Apache-2.0, or compound expressions like MIT OR Apache-2.0. Use the reserved value NOASSERTION when the license cannot be determined, or NONE when no license is granted. | yes |
| url | string | Link to the full license text. Absolute URLs (e.g. a LICENSE file in the upstream repository) are linked as-is. Relative paths (e.g. LICENSE.md) are resolved against the application's registry directory and can be used when the license file is shipped alongside manifest.json. | no |
| notes | string | Free-form notes about the license (max 500 characters). Recommended when spdx is NOASSERTION to document why the license is unclear (e.g. unknown author, distributed without a license file). | no |
{
"spdx": "GPL-2.0-only",
"url": "https://github.com/emukidid/cleanrip/blob/master/LICENSE"
}{
"spdx": "MIT",
"url": "LICENSE.md"
}{
"spdx": "NOASSERTION",
"notes": "Source archive found on a fan site with no LICENSE file; original author unknown."
}External resources
external_resources optional type array External links the user must follow manually. Two roles are supported:
download: replaces the registry-hosted install. Used when redistribution of the application itself is not permitted; omitsourcein that case and the catalog will surface this link (and QR code) instead of an install button.assets: supplements an installed app with files the user must obtain themselves (e.g. licensed game assets, original game data).
Item properties
| Name | Type | Description | Required |
|---|---|---|---|
| type | string | Role of the link: download or assets. | yes |
| label | string | Human-readable caption shown next to the link or under the QR code (max 100 characters). | yes |
| url | string | Absolute URL the catalog links to and encodes into the QR code. | yes |
| notes | string | Optional explanation shown alongside the link (max 500 characters). | no |
[
{
"type": "download",
"label": "Download from author's site",
"url": "https://example.com/app.zip",
"notes": "License does not permit redistribution"
}
][
{
"type": "assets",
"label": "Original DOOM WAD",
"url": "https://www.doomworld.com/classicdoom/info/shareware.php",
"notes": "Required licensed asset; place doom1.wad next to the .dol after install"
}
]Source
source optional type object Defines where to download the application binary. Exactly one variant must be configured, identified by the type discriminator.
Optional only if
external_resourcescontains an entry oftype: "download", used for apps that can't be redistributed by the registry. Otherwisesourceis required.
GitHub release
Download an asset from a GitHub release.
Properties
| Name | Type | Description | Required |
|---|---|---|---|
| type | Discriminator identifying this source as a GitHub release. Constant Value: "github_release" | yes | |
| repository | string | GitHub repository in owner/repo format. Nested groups are not supported.Pattern: ^[^/]+/[^/]+$ | yes |
| asset_pattern | string | Picomatch glob pattern matched against release asset filenames. Selects the asset to download. Minimal Length: 1 | yes |
| ignore_versions | string[] | Release tag names (or picomatch glob patterns) to skip when resolving the latest version. | no |
{
"type": "github_release",
"repository": "emukidid/swiss-gc",
"asset_pattern": "swiss_r*.7z"
}{
"type": "github_release",
"repository": "emukidid/swiss-gc",
"asset_pattern": "swiss_r*.7z",
"ignore_versions": ["v1.0-beta", "nightly*"]
}GitHub Actions artifact
Download an artifact produced by the latest successful run of a GitHub Actions workflow on a given branch.
Properties
| Name | Type | Description | Required |
|---|---|---|---|
| type | Discriminator identifying this source as a GitHub Actions artifact. Constant Value: "github_actions" | yes | |
| repository | string | GitHub repository in owner/repo format.Pattern: ^[^/]+/[^/]+$ | yes |
| workflow | string | Workflow filename (e.g. build.yml) located under .github/workflows/.Minimal Length: 1 | yes |
| branch | string | Branch whose latest successful run will be picked. Minimal Length: 1 | yes |
| artifact_pattern | string | Picomatch glob pattern matched against the artifact name as exposed by the GitHub Actions API. The matched artifact's name becomes the saved filename, so include any extension you want as part of the pattern. Minimal Length: 1 | yes |
{
"type": "github_actions",
"repository": "emukidid/swiss-gc",
"workflow": "build.yml",
"branch": "master",
"artifact_pattern": "swiss-nightly"
}GitLab release
Download an asset from a GitLab release.
Properties
| Name | Type | Description | Required |
|---|---|---|---|
| type | Discriminator identifying this source as a GitLab release. Constant Value: "gitlab_release" | yes | |
| repository | string | GitLab project path in owner/repo format. Subgroups are not supported.Pattern: ^[^/]+/[^/]+$ | yes |
| asset_pattern | string | Picomatch glob pattern matched against release asset filenames. Minimal Length: 1 | yes |
| ignore_versions | string[] | Release tag names (or picomatch glob patterns) to skip when resolving the latest version. | no |
{
"type": "gitlab_release",
"repository": "group/project",
"asset_pattern": "build-*.tar.gz"
}{
"type": "gitlab_release",
"repository": "group/project",
"asset_pattern": "build-*.tar.gz",
"ignore_versions": ["v1.0-beta", "nightly*"]
}itch.io
Download an upload from an itch.io game page.
Properties
| Name | Type | Description | Required |
|---|---|---|---|
| type | Discriminator identifying this source as an itch.io upload. Constant Value: "itchio" | yes | |
| creator | string | itch.io username of the creator. Forms part of the URL: https://[creator].itch.io/[game].Minimal Length: 1 | yes |
| game | string | itch.io game/project slug. Forms part of the URL: https://[creator].itch.io/[game].Minimal Length: 1 | yes |
| upload | string | Picomatch glob pattern matched against an upload's display name or filename on the itch.io download page. The first matching upload is selected. Minimal Length: 1 | yes |
| format | string | Expected file extension of the downloaded asset. Used to assemble the local filename {game}.{format}.Minimal Length: 1 | yes |
| version_pattern | string | Regular expression used to extract the version from the matched upload's display name or filename. The first capture group (or the whole match when there is no group) becomes the version. Overrides the default heuristic, which takes the first dotted number (e.g. 1.20); if neither produces a match, a {date}-{md5} identifier is used.Format: "regex"Minimal Length: 1 | no |
| version | string | Hardcoded version string. When set, it is used verbatim as the version, overriding auto-detection and version_pattern. The release is not re-checked until this value changes, so bump it manually to publish a new build.Minimal Length: 1 | no |
{
"type": "itchio",
"creator": "artemiourbina",
"game": "240p-test-suite",
"upload": "240p Test Suite for GameCube*",
"format": "zip"
}{
"type": "itchio",
"creator": "artemiourbina",
"game": "240p-test-suite",
"upload": "240p Test Suite for GameCube*",
"format": "zip",
"version_pattern": "(\\d+\\.\\d+)"
}{
"type": "itchio",
"creator": "artemiourbina",
"game": "240p-test-suite",
"upload": "240p Test Suite for GameCube*",
"format": "zip",
"version": "1.0"
}Direct URL
Download from a direct URL. Used when the application is not hosted on a Git forge or itch.io.
Properties
| Name | Type | Description | Required |
|---|---|---|---|
| type | Discriminator identifying this source as a direct URL download. Constant Value: "direct_url" | yes | |
| url | string | Direct download URL of the application binary or archive. Format: "uri" | yes |
| file_name | string | Override the filename derived from the URL. Useful when the URL does not contain a meaningful filename. Minimal Length: 1 | no |
| version | string | Hardcoded version string. When set, it is used verbatim as the version instead of the generated {date}-{sha256} identifier. The release is not re-checked until this value changes, so bump it manually to publish a new build.Minimal Length: 1 | no |
{
"type": "direct_url",
"url": "https://example.com/app.zip"
}{
"type": "direct_url",
"url": "https://example.com/app.zip",
"version": "1.0"
}Treatments
treatments required type array Ordered list of post-download processing steps applied to the downloaded asset. Treatments are executed sequentially. Each entry is identified by its treatment discriminator, which determines the operation and the shape of arguments.
The build pipeline operates on two scratch locations:
- Work directory: temporary scratch space where the downloaded source archive is unpacked and intermediate files live. Treatments use this as the staging area while assembling the final package.
- Dist directory: the final on-device layout. Once all treatments have run, this directory is packaged into a ZIP archive; that ZIP is what end users download to their consoles.
Treatments must shape the dist directory to match the on-device layout described in the distribution guide (typically apps/{slug}/default.dol, and optionally opening.bnr).
Extract archive
Extracts an archive (ZIP, 7z, TAR, etc.) inside the work directory. Typically used to unpack the source archive that was just downloaded. Uses 7-Zip under the hood.
Treatment: archive.extract
Arguments
- Archive pattern (string, required): Glob pattern matching the archive file(s) to extract from the work directory.
- Destination (string, required): Sub-directory inside the work directory to extract into. Use
.for the work directory itself.
{
"treatment": "archive.extract",
"arguments": ["swiss_r*.7z", "."]
}Move contents
Moves files from the work directory into the dist directory. This is how built artifacts (executables, banners, assets) are promoted into the final on-device layout.
Treatment: contents.move
Arguments
- Source pattern (string, required): Glob pattern matching files in the work directory to move. If the pattern ends with
/, all contents of that directory are moved. - Destination (string, required): Target path inside the dist directory. End with
/to treat as a directory. Parent directories are created automatically.
{
"treatment": "contents.move",
"arguments": ["cleanrip-gc.dol", "apps/cleanrip/default.dol"]
}Delete contents
Deletes files from the work directory. Useful for dropping extras from an extracted archive (READMEs, sample files, debug builds) before moving a whole directory into the dist directory with contents.move.
Treatment: contents.delete
Arguments
- Pattern (string, required): Glob pattern matching files inside the work directory to delete. Deletes recursively.
{
"treatment": "contents.delete",
"arguments": ["*.txt"]
}Copy from registry
Copies files from the app's registry entry directory (the folder in DolphinDepot/registry that contains its manifest.json) directly into the dist directory. Use this for static assets that ship with the manifest itself, most commonly opening.bnr.
Treatment: registry.copy
Arguments
- Source pattern (string, required): Glob pattern matching files inside the app's registry entry directory.
- Destination (string, required): Target path inside the dist directory. End with
/to treat as a directory.
{
"treatment": "registry.copy",
"arguments": ["opening.bnr", "apps/my-app/opening.bnr"]
}Create directory
Creates an empty directory in the dist directory, including any missing parent directories (like mkdir -p). Use this when the app expects a directory (e.g. for saves or config) that isn't shipped in the downloaded asset.
Treatment: contents.mkdir
Arguments
- Path (string, required): Directory path inside the dist directory. Parent directories are created automatically; an existing directory is left untouched.
{
"treatment": "contents.mkdir",
"arguments": ["apps/my-app/saves"]
}Download from URL
Downloads an additional file from a URL into the work directory. Use this to fetch assets that aren't bundled with the primary source download; they can later be moved into the dist directory with contents.move.
Treatment: web.download
Arguments
- URL (string, required): Direct download URL of the file. Must be a valid URI.
- Destination (string, required): File path inside the work directory to save the download to.
{
"treatment": "web.download",
"arguments": ["https://example.com/asset.bin", "extra/asset.bin"]
}