Appium integration with Device Tunnel
Running Appium sessions over Device Tunnel for Android and iOS
Device Tunnel provides raw ADB and USB access to a remote device. You can run a local Appium server on top of this tunnel to automate the device as if it were physically connected. This section covers the complete setup for both Android and iOS.
The Device Tunnel handles the physical transport layer. Appium communicates with the device through the tunnel just as it would with a locally connected device, over ADB (Android) or usbmuxd and iproxy (iOS).
Prerequisites
- Appium installed globally:
npm install -g appium - Always use the latest available Appium version and latest driver versions for best performance
- Android:
appium driver install uiautomator2(latest version) - iOS:
appium driver install xcuitest(latest version) -
adbinstalled and in$PATH(Android) -
libimobiledevicetoolchain installed:iproxy,ideviceinstaller,ideviceinfo(iOS)
Android
On Android, Appium communicates with the device through the ADB tunnel port (localhost:<port>) set up by the connect command. The uiautomator2 driver and its APKs are managed by Appium on the user host side; nothing is pre-installed on the device.
Appium installs and verifies the UiAutomator2 server APKs over the tunnel, so the process can occasionally fail on the first attempt. Retry the Appium session. Subsequent attempts succeed once the APKs are in place.
Establish the device tunnel connection
Note the ADB port printed in the output (e.g., ADB port: 7005). The device will be reachable at localhost:7005.
(Optional) Stop any leftover UiAutomator2 processes
If a previous session left UiAutomator2 running, stop it before starting a new one:
Start the local Appium server
Launch your Appium session with these capabilities
Capability notes:
| Capability | Reason |
|---|---|
appium:udid |
Must be localhost:<adbPort>, the ADB tunnel address, not the physical UDID |
appium:uiautomator2ServerInstallTimeout |
To increase the install timeout to prevent timeouts |
appium:androidInstallTimeout |
To increase the install timeout to prevent timeouts |
appium:suppressKillServer |
To prevent ADB from killing the server |
iOS
On iOS (iOS 17 and above), Xcode remote build is not supported over device tunnel. Appium cannot build or start XCUITest process via xcodebuild commands on the device through the tunnel. Instead, you must use the pre-installed WDA already present on the dedicated device and forward its port to your machine using iproxy.
Forward the WDA port with iproxy
For example, if wdaPort is 8400 and the device UDID is 00008110-000231CC02D1401E:
This forwards device port 8400 → local port 8100. You can use any free local port; just keep it consistent with your Appium capabilities.
You can use any available port in place of 8100.
Verify WDA is reachable before starting Appium:
Start the local Appium server
Launch your Appium session with these capabilities
Capability notes:
| Capability | Reason |
|---|---|
appium:udid |
Physical device UDID (not localhost:<port> like Android) |
appium:usePrebuiltWDA |
Tells Appium to use the existing WDA already running on device, do not rebuild it |
appium:useNewWDA |
Must be false, which prevents Appium from trying to launch a new WDA process |
appium:webDriverAgentUrl |
Must match the local port you chose in iproxy (e.g., http://localhost:8100) |
appium:wdaLocalPort |
Must match the local port you chose in iproxy (e.g., 8100) |
WDA version: The pre-installed WDA on dedicated devices tracks BrowserStack’s supported WDA version. You cannot downgrade or change the WDA version on the device. Always use the latest xcuitest driver which is compatible with the installed WDA.
If WDA crashes: If the WDA process is killed (e.g., by the device OS or a cleanup script), Appium sessions will fail to connect. Trigger session stop or tunnel stop command and post cleanup the WDA will be up and running again. Do not attempt to reinstall or rebuild WDA yourself.
App installation
Do not install apps through Appium. For large app binaries, Appium’s install pathway can time out or behave unpredictably over the tunnel. Install apps separately before starting your Appium session.
Android
For example:
Verify installation:
iOS
For example:
iOS provisioning profiles: The IPA must be re-signed with a provisioning profile that explicitly includes the UDID of the dedicated device. Apps signed for a different device or with an ad-hoc profile for the wrong UDID will fail to install. Contact your iOS developer to create a provisioning profile that includes the dedicated device UDID.
Verify installation:
Known Appium limitations over tunnel
| Limitation | Detail |
|---|---|
| iOS WDA build not supported | Xcodebuild process and commands over tunnel does not work on iOS 17+. Must use pre-installed WDA with usePrebuiltWDA: true. |
iOS appium-ios-device library |
Appium’s Node.js iOS device library uses usbmuxd in a way that does not work through the tunnel. |
| Android APK signing requires JAVA_HOME | If JAVA_HOME is not set, use skipServerInstallation, skipDeviceInitialization, and noSign caps to bypass APK verification. |
| No Appium-driven app install (iOS) |
app capability with an IPA path will fail or time out. Pre-install using ideviceinstaller instead. |
| iproxy must stay running | The iproxy process must remain alive for the entire Appium session. If it exits, WDA communication is lost. |
| Any issue during appium start | Install the app separately via ideviceinstall or adb install and only provide the bundleID during appium session start, that should help unblocking and reach out to browserstack support with appium logs. |
We're sorry to hear that. Please share your feedback so we can do better
Contact our Support team for immediate help while we work on improving our docs.
We're continuously improving our docs. We'd love to know what you liked
We're sorry to hear that. Please share your feedback so we can do better
Contact our Support team for immediate help while we work on improving our docs.
We're continuously improving our docs. We'd love to know what you liked
Thank you for your valuable feedback!