A Menu Bar App for One-Click Mobile Testing
Manual testing of pull requests is part of Shopify’s engineering culture. The practice, called “tophatting,” dates back to when GitHub didn’t support PR reviews and reviewers signaled approval with a tophat emoji after validating changes locally. But the process of stashing work, switching branches, and waiting for Xcode or Android Studio to compile added up to significant lost time. The team set out to remove that friction by building a macOS app called Tophat that lives in the system menu bar and launches builds from GitHub PRs without requiring a local checkout or compilation.
The investment in this desktop tooling was driven by three factors: the ongoing migration of Shopify Mobile to React Native demands frequent testing on real devices; analytics showed low adoption of earlier tophatting tools, meaning developers were either testing less often or still compiling locally; and a unified interface for iOS and Android devices would become the foundation for future mobile tooling at Shopify.
How the Build Pipeline Works
Tophat exposes a lightweight HTTP web server linked from GitHub PRs, since GitHub doesn’t support custom URL schemes. In the Shopify Mobile repository, a bot runs as part of standard CI and stores build artifacts in Google Cloud Storage (GCS) buckets. The bot posts links to these artifacts on each PR, allowing reviewers to install the prebuilt iOS or Android app to a simulator or physical device with a single click—completely eliminating local compilation.
The app parallelizes installation tasks such as downloading the build and booting the target device. Every part of the interface, from the landing page animations to the menu bar design, was built with the goal of making the workflow enjoyable enough that developers would actually use it.
Tophat also extends beyond PR review. React Native development typically relies on Metro, the JavaScript bundler that watches for changes and updates the running app. Developers can attach any build to their local bundler, but occasionally need a fresh build after modifying native Swift or Kotlin code. A feature called “Quick Launch” in the Tophat interface grabs the latest native build, so when developers start new work they can click the app in the palette and begin JavaScript changes, confident that all native modules are current.
Overcoming Real-Device Limits on iOS
Simulators are a reasonable approximation, but only testing on real hardware reveals how an app actually behaves. Android’s adb tool handles installation and launching on both emulated and physical devices. iOS has simctl for simulators, but no first-party equivalent for real devices. There’s also the signing problem: installing on a physical iPhone or iPad requires a development, enterprise, or distribution certificate, and CI artifacts were previously unsigned for simulator-only use.
Two problems needed solving:
- Find a way to install apps on real iOS devices.
- Sign builds for real devices with a development certificate that minimizes the setup burden on contributors.
Choosing the Installation Tool
Apple restricts app installation to the App Store, enterprise distribution, or Xcode during development. There are no publicly documented APIs for remote installation and launching. macOS uses a private framework called MobileDevice.framework to communicate with attached devices, but rather than reverse-engineering private headers or adopting a full protocol reimplementation, Shopify settled on the community-maintained ios-deploy utility, which provides a CLI over MobileDevice.framework using reverse-engineered headers. Tophat bundles ios-deploy directly, so developers don’t need to install extra dependencies.
Handling Code Signing
iOS apps can be signed with three certificate types, each with tradeoffs:
- Development: Valid for about a week; requires an embedded provisioning profile listing allowed devices. The device UDID must be registered in the Apple Developer Portal. Ideal for debugging but annoying for initial setup.
- Enterprise: Available only to Enterprise Program members; works indefinitely on unlimited devices with no provisioning profile. But it disables the
get-task-allowentitlement needed for remote launching and debugging. - Distribution: For App Store submissions only.
Shopify first tried communicating with Apple’s internal Developer Portal APIs, as Xcode does, to automate provisioning and signing. The lack of public documentation made the process fragile and inconsistent. Re-signing an app bundle manually was also tricky, because every app can have a different layout of Executables, Frameworks, and App Extensions.
The solution was Shopify’s existing Fastlane match utility, which manages signing certificates automatically across the company. The Mobile Tooling team had already set up a YAML-based API for code signing management, so Tophat could simply configure an Apple Development certificate and sign bundles in CI. Developers need to provision their devices manually once, after which certificates and provisioning profiles update automatically—not quite as magical as full automation, but guaranteed to work.
To aid troubleshooting, Tophat includes checks that notify developers when a device isn’t provisioned or the app bundle is missing required entitlements. It also verifies the signing certificate contains the iPhone Software Development Signing extension object identifier (OID) using APIs from the Apple Security framework.
With Installation handled and signing automated, Tophat now provides a physical device development experience comparable to Xcode or Android Studio, installing builds over USB or Wi-Fi and launching them automatically with one click.
Making Onboarding Effortless
Tophat began as an internal tool for Shopify Mobile contributors, but the goal was always to make it the standard way to install builds for any mobile project at Shopify — without requiring developers to perform manual setup steps if they already had a working development environment.
Shopify's Dev tool includes a configurable command called dev up that automatically installs everything needed to start working on a project. Tophat was integrated into this command, so it gets installed automatically for all mobile developers. To make the setup fully invisible, Tophat's settings also needed to be preconfigured and wired into existing tooling. That led to tophatctl, a command-line utility callable from dev up steps across projects. It can populate the Quick Launch palette and launch applications.
An onboarding flow verifies that everything needed is in place: Xcode, Android Studio, the Google Cloud SDK for downloading CI artifacts, and the tophatctl helper. In practice, most developers see all green check marks because Dev already configures all dependencies, but installation instructions are included for cases where manual configuration is necessary.
Tophat is also integrated into Shopify's internal release tool, Shipit Mobile, a web application that works with GitHub and Slack to automate mobile releases. Shipit Mobile can create internal "snapshot" builds from pull requests and specific commits on demand, or on a nightly schedule. With Tophat links embedded directly in Shipit Mobile, any project already using it can install snapshot builds onto virtual or real devices with a single click.
The design principle is straightforward: make powerful tools available by default. By integrating Tophat into existing tooling and supporting fully unsupervised installation, every Shopify developer working on a mobile project gains Tophat support without any manual effort.
What Comes Next
Daily usage analytics show the number of Tophat uses per day has doubled since these improvements shipped. Developer feedback has been positive, and two enhancements stand out as next steps:
- Device Management: Eliminating the need to open Xcode or Android Studio for daily work would require integrating device management directly into Tophat, making it the central native mobile development tool.
- Bundled Dependencies: Tophat relies on a fully functioning mobile development environment, which means non-developers like UX or Product teams still need to set one up. Shopify's Dev tool can install prerequisite toolchains, but the hope is to bundle more development tools directly into Tophat so non-developers only need to drag it into their Applications folder.
Internal tools like Tophat are essential for efficient mobile development at scale. Reducing time spent recompiling the same codebase shortens feedback loops and accelerates feature delivery. Tophat has been made open source so the broader mobile developer community can put it to use as well.



