# Contribute an app

The [Awesome List](https://ipa-hub.giladgd.com/docs/guide/awesome-list.md) is a curated collection of apps with downloadable IPA releases. Suggest an app by opening a pull request with an entry, its icon source URL, and attribution. You do not need to add image files or edit the website's React components or generated documentation.

## Add an entry

After [setting up the repository](https://ipa-hub.giladgd.com/docs/guide/development.md), add an object to `docs/awesome-apps.json`. Use an existing entry as a starting point:

```json
{
    "id": "utm",
    "title": "UTM",
    "description": "Run virtual machines on your iPhone, iPad, or Vision Pro with UTM SE.",
    "repo": "utmapp/UTM",
    "website": "https://getutm.app",
    "iconSource": "https://raw.githubusercontent.com/utmapp/UTM/COMMIT_SHA/Platform/Assets.xcassets/AppIcon.appiconset/Icon.png",
    "license": {
        "name": "Apache-2.0; bundled components have other licenses",
        "url": "https://github.com/utmapp/UTM/blob/main/LICENSE"
    },
    "installs": [
        {"platforms": ["iphone", "ipad"], "filter": "^UTM-SE$"},
        {"platforms": ["visionos"], "filter": "^UTM-SE-visionOS$"}
    ]
}
```

Replace `COMMIT_SHA` with the full 40-character commit hash containing the icon. IDs, repositories, and platform defaults must be unique. Unknown fields are rejected so a misspelled filter cannot silently change the generated command.

| Field | What to provide |
| --- | --- |
| `id` | A stable lowercase slug, such as `my-app` |
| `title` | The app's name, up to 80 characters |
| `description` | Plain text describing what the app does, up to 300 characters; searchable on the list |
| `repo` | The public GitHub `owner/repository` that publishes the IPA |
| `website` | Optional HTTPS URL for the project's official website |
| `iconSource` | The upstream `raw.githubusercontent.com` URL, pinned to a commit in that repository |
| `license` | The license name and a link to its file in the repository; describe custom or mixed licensing accurately |
| `installs` | Platform groups and the default filename filter for each group |
| `featured` | Optional boolean; maintainers select which icons appear on the landing page |

## Choose a useful default

An install option contains `platforms`, `filter`, and optionally `release`. Omit `release` to track the latest stable release. Use `prerelease` for the newest prerelease, or a tag to select a specific release.

Supported platform values are `iphone`, `ipad`, `appletv`, `visionos`, and `applewatch`. Include only platforms supported by that particular IPA, based on the project's documentation and your testing. Each platform can appear in only one option for an app. Use separate options when different platforms need different IPA files.

The [filename filter](https://ipa-hub.giladgd.com/docs/guide/sources.md) must match exactly one IPA in the selected release. Matching is case-insensitive. Text such as `tv` matches anywhere; `advanced*tv` matches separated text segments. A filter beginning with `^` or ending with `$` uses a regular expression. Names are checked without the `.ipa` suffix first. Prefer stable parts of filenames rather than version numbers.

Choose builds intended for ordinary re-signing where possible. Describe any additional setup in your pull request: re-signing alone does not enable JIT or satisfy every entitlement requirement. Apps without a published IPA are not included.

## Provide the icon source and attribution

Point `iconSource` at a square PNG between 128 and 2048 pixels on each side, no larger than 5 MB. Validation and website builds fetch missing icons automatically: first from `https://ipa-hub.giladgd.com/assets/awesome-apps/<id>.webp`, then from `iconSource` if the published image is unavailable or invalid. If neither works, the build fails.

Downloaded icons are cached as `assets/awesome-apps/<id>.webp`. This directory is gitignored, and subsequent builds reuse its files without downloading them again. Remove a cached file to fetch it again. Attribution files remain tracked separately.

Create `assets/licenses/awesome-apps/<id>.txt` with the app name, the exact `iconSource` URL, the exact license URL, and the applicable upstream license and attribution notices. Check whether artwork has separate terms and preserve those too. The website publishes these notices alongside the icons. Do not add artwork you are not permitted to redistribute.

## Validate and open a pull request

```shell
npm run validate:awesome
npm run validate:awesome -- --check-releases
```

The first command checks the JSON, duplicate entries, platform defaults, icons, and attribution files, downloading any missing icons. The second also checks GitHub releases using the same filename matcher as `ipa-hub install`. Each default filter must select exactly one uploaded IPA. Set the `GITHUB_TOKEN` environment variable if you encounter GitHub's unauthenticated rate limit; never put a token in the catalog or pull request.

CI runs both checks. Normal documentation and website builds validate the catalog and fetch missing icons without fetching GitHub releases. To preview your change, run `npm run dev:website` and open the Awesome List from the version menu.

In your pull request, describe what the app does, link to the release, and list the devices and OS versions you tested. Maintainers review suitability, platform support, and licensing before merging. CI checks the catalog and release assets; it does not run or endorse the apps.

