Jul 4, 20266 min read/2026/07/04/no-adb-for-iphone-automating-react-native-ui-tests-on-real-ios-devices/

There's No ADB for iPhone: Automating React Native UI Tests on Real iOS Devices

If you come from the Android world like I do, you probably have a comfortable little habit: plug in a physical device, talk to it over adb, and automate everything from installs to UI taps with a shell script. It's fast, it's local, and it works against basically anything on the device.

So the natural question when you start shipping the iOS side of a React Native app is: can I do the same thing on a physical iPhone?

The short answer is yes, but. And the "but" is bigger than I expected, so I want to walk through the whole thing — the differences from ADB, the React Native-specific tooling, and the one catch that lands squarely on the thing I care about most: running on a real device instead of a simulator.

First difference: you can only automate your own app

On Android, adb shell input tap, screencap, and UIAutomator dumps work against any app on the device, including ones you didn't build. That's why so many people (myself included) end up scripting third-party apps this way.

iOS does not let you do that. There is no system-wide input injection into apps you don't control. Every UI automation runner on iOS — XCUITest, WebDriverAgent, and everything built on top of them — runs as a signed test process tied to a provisioning profile, and the sandbox stops you from poking at arbitrary third-party apps the way you can on Android.

The good news: this restriction doesn't matter when you're testing your own app, which is the whole point here. Full gray-box or black-box automation of an app you build and sign is completely doable. Just don't expect to script someone else's app on a non-jailbroken iPhone the way you can on Android.

The React Native angle: Detox is the "native" tool, but read the fine print

For React Native specifically, the tool everyone reaches for first is Detox (built by Wix).

Detox is gray-box: it instruments the React Native bridge and automatically synchronizes with your app's async operations. That means no flaky sleep() calls scattered through your tests, and you select elements by the testID props on your components instead of brittle coordinate taps. It's the closest thing React Native has to a real UIAutomator analog, and it has the lowest flakiness of any option because of that synchronization.

Here's the catch, and it's the important one: Detox's iOS support is built around the Simulator. Officially it supports real Android devices and iOS simulators. Physical iOS device support is the weak spot — reports put real-device reliability low, with animation synchronization problems on actual hardware.

So Detox is fantastic if you're willing to run your iOS tests on the Simulator. It is the wrong tool if you specifically want the physical-device parity you already have with ADB on Android.

Why I want a real device anyway

This is exactly where I landed. Two reasons push me off the simulator:

  1. Memory problems. The simulator's memory ceiling bites hardest precisely when you're hammering it with automated flows. If you've fought this, you know.
  2. Real devices just feel right. Simulators paper over GPU behavior, thermal throttling, gesture timing, sensor quirks, and memory-constraint bugs. A physical device surfaces the things your users will actually hit.

So "just use the Simulator" isn't a satisfying answer for me. That pushes the decision toward Maestro or Appium — and this is where I had to double-check the current state of things, because it's a moving target.

The physical-device catch (this is the whole article, really)

Here's the accurate picture as of mid-2026.

Maestro — not officially local on iOS yet

Maestro is lovely: human-readable YAML flows, black-box via the accessibility tree, cross-platform, and minutes to set up. On Android it talks to real devices directly through ADB.

But on iOS, Maestro does not officially support running on a physical device connected to your Mac. Its official iOS targets are the Simulator and cloud device farms. The Maestro team has signaled that official local real-device support is still coming, with no committed timeline — so you can't count on it landing soon.

The root cause is the same theme as everything else here: there's no ADB equivalent that Apple exposes, so there's no direct local bridge to a physical iPhone.

There is a workaround: an unofficial community tool called maestro-ios-device (from DeviceLab, built from Maestro PR #2856) patches Maestro to run on real iPhones and iPads via an XCTest driver with automatic port forwarding. It works, and it even does parallel real-device runs. But it's explicitly "use at your own risk," and some commands are limited by iOS itself:

  • clearState works only via app reinstall (requires --app-file)
  • setLocation needs extra setup
  • addMedia isn't supported

It's a reasonable option if you love Maestro's authoring model and you'll accept an unofficial dependency that you plan to swap out once official support ships.

Appium — the honest official answer for local real devices

Appium with the XCUITest driver natively supports local physical iOS devices over USB. It's mature, it's the most ADB-like cross-platform harness available, and it integrates with device farms (BrowserStack, Sauce Labs) if you ever want to scale out.

The cost is what you'd expect from the veteran tool: it's more verbose (explicit driver setup, capability configuration, session management) and slower than Maestro because of the WebDriver protocol layer. It's also black-box, so you don't get Detox's bridge synchronization.

But if a local physical device is a hard requirement and you want something officially supported, Appium is it.

Cloud device farms — real, but not local

TestingBot added Maestro physical-iOS support in January 2026, and BrowserStack offers real iOS devices too. These give you real hardware, but remote hardware — great for CI breadth, not for the hands-on, day-to-day device feel I'm after.

The unavoidable Apple tax

Whichever route you pick, the Apple prerequisites are identical and non-negotiable:

  • A Mac with Xcode (any XCUITest- or WebDriverAgent-based runner has to be built and code-signed on macOS — there's no way around this)
  • An Apple Developer account for signing certificates and provisioning profiles
  • The device registered (its UDID) and trusted
  • Developer Mode enabled (iOS 16+)

That signing-and-provisioning layer is the real friction. It's exactly the thing ADB spares you from on Android, and it's why the iOS story will always feel heavier no matter which tool you land on.

My recommendation

Here's the decision tree I ended up with:

  • If you can live with the iOS Simulator → use Detox. You get one clean React Native-native suite with testID selectors and low flakiness across both platforms. Simplest overall.
  • If a physical device is non-negotiable and you want something supported that just works → use Appium. Local real-device support is official and mature. Accept the verbosity.
  • If Maestro's YAML simplicity matters enough that you'll tolerate an unofficial patch until official support ships → use the DeviceLab maestro-ios-device route.
  • If you only need real-device coverage in CI, not on your desk → a cloud device farm covers it.

For me, with the simulator memory problems and a strong preference for testing on real hardware, the physical device wins — which means Appium is the pragmatic, supported choice, with the Maestro-patch route as a tempting lightweight alternative.

The one-sentence takeaway

There is no ADB for iPhone, and that single fact explains everything: your app must be signed, your runner must be a signed test process, and "just plug in a real device and script it" — the thing you take for granted on Android — is the exact thing Apple makes you work for on iOS.


Notes for future me: next step is writing up the concrete Appium + WebDriverAgent setup against a connected iPhone for a React Native app — the provisioning steps are where people lose the most time.