# Tophat installs a mobile build from a link, on the device you point at

> Tophat is a macOS application for installing and testing iOS and Android builds without building branches locally, using URLs of the form tophat://install/<provider> with query parameters, a set of artifact providers that say where a build comes from, recipes that let one link cover a simulator and a device, and a tophatctl command line helper for scripting. It is MIT licensed, developed by Shopify, and version 2.6.0 was published on 2026-08-31.

**Shopify/tophat** — Easily install and test mobile applications with a single click.

- Repository: https://github.com/Shopify/tophat
- Stars: 1,076 · Forks: 42
- Language: Swift
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/shopify-tophat

## The problem is that a build is not an app

The description is that Tophat is the best way to install and test any mobile application, and the pitch is one click installation with just CI added. The problem it solves is not that building an app is hard, it is that a build artifact is not an installable thing. An .ipa or an .apk has to be signed, provisioned, and pushed onto a specific device, and doing that by hand for every pull request is what makes testing a branch expensive. Tophat's answer is to make the install a URL. You skip building branches locally, use Tophat's features and APIs to easily create installation links to CI artifacts, and take it a step further to offer contributors the ability to test pull requests without cloning anything. The audience is a mobile team with continuous integration and a lot of people who need to try a build but do not have a development environment.

## The URL is the API

Tophat handles URLs using both the tophat:// and the http:// schemes so that you can use them in any website or application, and the README suggests preferring the tophat:// scheme because it does not navigate away from the current page. The examples use tophat://, and it is interchangeable with http://localhost:29070/, which is what you use for GitHub. The format names the provider and passes parameters:

```text
tophat://install/gcs?bucket=<bucket>&object=<object>
```

The type of build downloaded is interpreted by Tophat automatically, but the API lets you preheat the intended device by specifying the platform and the destination:

```text
tophat://install/gcs?bucket=<bucket>&object=<object>&platform=ios&destination=device
```

If multiple artifacts exist for different destinations, the parameters for both are given in the same URL by repeating the query parameters, and Tophat selects the appropriate ones for the selected device. Launch arguments travel in an arguments query parameter, as a comma separated list:

```text
tophat://install/gcs?bucket=<bucket>&object=<object>&arguments=one,two,three
```

On iOS those arguments are retrievable with ProcessInfo, and on Android they are delivered to the main activity through intent argument extras in the TOPHAT_ARGUMENTS key as an array of strings. That last detail is what lets a build know which variant it is, which is how a server can point the same install at a staging backend.

## Providers and recipes

Downloads with Tophat are powered by artifact providers, some built in and some installable as Tophat Extensions. An install request needs the provider's ID, the provider's parameters, and optionally the platform, the destination and a list of launch arguments, and the format varies slightly between URLs, Quick Launch and tophatctl, but every API needs roughly the same information. You can list all the provider IDs with tophatctl list providers. A request can install multiple artifacts, and within a request these are called recipes, which the README says are particularly useful when you want one link that supports both simulators and devices, where different builds are required for each. That is the feature that makes a Tophat link useful in a chat, because a single message works whether the person opens it on a simulator or on their phone.

## The shell script provider hands you the download

Two providers are built in, and one of them gives you complete control. The basic HTTP provider is a URL and nothing more:

```text
tophat://install/http?url=<full_public_url>
```

The shell script provider allows you to have full control over how the artifact is downloaded. The scripts are placed in ~/Library/Application Scripts/com.shopify.Tophat.TophatCoreExtension/ and must have their executable flags set with chmod +x, and they are invoked with:

```text
tophat://install/shell?script=filename
```

The script gets two positional arguments. The first is a full path to a staging directory where you may temporarily store files during the download and the unzip, and the second is a full path to the output directory where exactly one artifact must be located when the script finishes, because Tophat looks in that directory to install the application. The contract is strict in a useful way, since the script has to fetch, unpack and place the artifact in a known location, which means it can do anything from an internal artifact store to a decrypt step to a corporate proxy.

## tophatctl is the scripted path

Tophat can be integrated into various tools and projects using tophatctl, the companion command line app, and the README lists three jobs for it. It can manage Quick Launch apps, so you can pre-populate Tophat with your project's apps in a dev up step. It can install an app by URL or path. And it can list providers, displaying provider configuration to assist with integration. The details are in the command's own help, which you run after installing the Command Line Helper:

```sh
tophatctl --help
```

The command line helper is the piece that fits into a dev script, so a contributor can run one command after a build and have the app on their device, and the Quick Launch task is what keeps the app list in sync with the projects on the machine.

## The parts that make it a daily tool

Several features are less about installation and more about the daily friction around it. Quick Launch allows you to add your favourite apps right to the Tophat menu, and Tophat downloads the latest version, automatically updates the icon, and launches it on your device, so the menu is a launcher rather than a list. Device pinning exists for the case where you have lots of devices and only use a couple at a time, letting you pin them to the top of the devices list for quick access. The Settings window lets you adjust preferences, add apps to Quick Launch, and specify custom tooling paths so Tophat works in your environment. Tophat also adds file associations to .ipa, .apk and .zip files, so an artifact can be opened from the file manager or from a download. Getting started is a signed universal binary from the latest GitHub release, unpacked into the Applications folder, and the app checks for updates by itself.

## What Tophat is, and what it is not

Two boundaries are worth stating. The first is that Tophat is a development tool, not a distribution channel. It installs onto a device that is already set up for development, and every install still needs a signed artifact and a provisioning profile, so it does not remove the signing step that makes internal distribution hard. The second is version 2 of the API. The README notes that the APIs introduced in Tophat 2 have replaced the legacy ones, which have been removed, so an integration written against the older scheme has to be rewritten, and the model changed with it, from whatever the earlier API was to the provider, parameters, platform, destination and arguments model. The extensions story is the extension to that, since the TophatKit SDK lets you extend Tophat to integrate with custom build and caching systems, which is what makes the tool compatible with tooling setups the built-in providers do not cover, and the repository shows the pieces as separate directories, with Tophat, TophatCtl, TophatExtensions, TophatKit, TophatModules, TophatTests and a Tophat.xcodeproj. The licence is MIT, and the project has been described in a Shopify engineering blog post about mobile developer testing.

## Conclusion

Tophat is the right tool if your team ships mobile apps and your designers and product people need to install a build from a pull request without a Mac and an Xcode project, because the URL form is something you can paste into a chat message and because the provider model means the link survives your CI system changing. It is the wrong tool if you build for a single platform, since the value is in covering several destinations from one link, and it is the wrong tool if you need distribution to end users, since every install still needs a signed artifact and a provisioning profile. Before you build links on it, read the Tophat 2 note, since the APIs introduced in version 2 replaced the legacy ones, and decide early whether you need an extension, because a custom build system means writing a provider rather than a URL.

## FAQ

### What does Tophat actually do?

It installs iOS and Android builds onto a device without building branches locally, by turning a URL of the form tophat://install/<provider> with query parameters into an installation, so that contributors can test pull requests without cloning anything. It also adds file associations for .ipa, .apk and .zip files and a Quick Launch menu of your favourite apps.

### What is an artifact provider in Tophat?

It is the thing that knows where a build comes from. Some providers are built in, such as the basic HTTP provider and the shell script provider, and others are installable as Tophat Extensions. You can list all the provider IDs with tophatctl list providers, and an install request needs the provider ID and its parameters, with the platform, the destination and the launch arguments optional.

### How do I pass launch arguments to an installed app?

With the arguments query parameter in the install URL, as a comma separated list. On iOS the arguments are retrievable using ProcessInfo, and on Android they are delivered to your app's main activity through intent argument extras in the TOPHAT_ARGUMENTS key as an array of strings.

### What can tophatctl do?

Three things, according to the README. It manages Quick Launch apps, so you can pre-populate Tophat with your project's apps in a dev up step, it installs an app by URL or path, and it lists providers to display provider configuration for integration. The details are in tophatctl --help.

## Sources

- [Issues](https://github.com/Shopify/tophat/issues)
- [License: MIT](https://github.com/Shopify/tophat/blob/main/LICENSE)
- [README](https://github.com/Shopify/tophat/blob/main/README.md)
- [Releases](https://github.com/Shopify/tophat/releases)
- [Shopify/tophat on GitHub](https://github.com/Shopify/tophat)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/shopify-tophat
