By Jochen D.
Appium 2 was a large break from Appium 1, and Appium 3 is now the current major version. This guide covers both steps: what changed moving from Appium 1 to Appium 2, and what changed again in Appium 3. If you are on Appium 2 today, skip to the Appium 3 section.
In contrast to Appium 1, Appium 2 does not come with iOS and Android support by default. Instead, you now need to install the required drivers (and optional plugins), to activate the necessary functionality for your automated tests.
You can find out more by reading the official Appium 2 Changelog.
What has changed with Appium 2?
URL Changes
With Appium 1, the URL you needed to use in your tests was http://localhost:4723/wd/hub. The new URL with Appium 2 has been changed to http://localhost:4723/, which means the wd/hub part is no longer required. If you still want to use the Appium 1 URL, you can use this command:
appium --base-path=/wd/hub
Protocol Changes
With Appium 1.x, both MJSONWP (Mobile JSON Wire Protocol) and the W3C WebDriver protocol were supported. Starting with Appium 2, only the W3C WebDriver protocol is supported.
Driver installation required
With Appium 1, all drivers were installed as soon as you downloaded and installed Appium. This has changed with Appium 2, you now need to install the necessary drivers for your automated tests to work. The most popular drivers are listed below:
-
UIAutomator2 Driver for Android testing. To install, use this command:
appium driver install uiautomator2 -
XCUITest Driver for iOS testing. To install, use this command:
appium driver install xcuitest
We recommend to periodically check if there are any updates to these drivers, which may include fixes and optimizations for you tests. To check for Appium Driver updates, please use this command:
appium driver list --updates
Capabilities
Before Appium 2, you could specify whichever capabilities you wanted. Since Appium 2, only browserName and platformName can be specified without a vendor prefix. All other capabilities need to be prefixed with a string and colon, with for example appium: or tb:.
You can specify additional Appium options, such as:
appium:appappium:deviceName
Image Comparison Changes
Appium 1 supported various image comparison commands. Since Appium 2, the choice was made to move this feature into an Appium Plugin.
Plugins are components which can be added to Appium 2, that offer additional features. To install the image comparison library (used for visual testing), you can use this command with Appium 2.x:
appium plugin install images
Execute Driver Script: WebDriverIO
Execute Driver Script is a feature that allows you to run a WebdriverIO script and have it executed entirely on the server, instead of sending each command individually from the client. Since Appium 2.x, this functionality has been moved to a plugin, which can be installed:
appium plugin install execute-driver
External Files deprecated: --nodeconfig, --default-capabilities, --allow-insecure and --deny-insecure
These options can be specified as strings when entering commands through the command line. For --nodeconfig, you should use a JSON string, and for --allow-insecure and --deny-insecure, use comma-separated lists of strings. It's essential to remember that arguments provided via the command line might require quoting or escaping to work correctly.
However, it is now recommended to provide these options through a configuration file.
To do this, if you are using a JSON Appium config file, you can simply copy and paste the contents of your nodeconfig JSON file into the value of the server.nodeconfig property.
For --allow-insecure and --deny-insecure files that were previously in CSV-like format, you can now use them as the values of the server.allow-insecure and server.deny-insecure properties in the Appium config files, respectively. Both properties should contain arrays of strings.
Appium Desktop is now called Appium Inspector
Appium Desktop's inspector functionality has been separated into a dedicated application called Appium Inspector. This new app is fully compatible with standalone Appium 2.x servers and can also function with later versions of Appium 1.x servers. However, it's important to note that Appium Desktop itself has been deprecated and is not compatible with Appium 2.x.
Appium Inspector offers a browser version as well, accessible at https://inspector.appiumpro.com. If you intend to use the browser version with a local Appium server, you must first initiate the server with the --allow-cors flag to ensure seamless functionality.
What changed again with Appium 3?
Appium 3 is the current major version. If you are upgrading a suite that already runs on Appium 2, these are the changes most likely to break it. They are taken from the official Appium 2 to 3 migration guide, checked 31 August 2026.
The touch endpoints are gone
This is the big one for existing suites. TouchAction and MultiAction relied on endpoints such as /touch/perform and /touch/multi/perform, and Appium 3 removes them. They map onto the W3C Actions API at POST /session/:sessionId/actions, and most common gestures have a shorter driver-specific equivalent such as mobile: swipeGesture. We cover both in using touch actions with Appium.
Node 20 or newer
Appium 3 requires Node ^20.19.0 || ^22.12.0 || >=24.0.0 and npm 10 or newer. This catches a lot of CI images that were pinned years ago.
Insecure feature flags now need a scope
Feature names must be prefixed with the driver they belong to, and Appium 3 throws if they are not. So --allow-insecure=adb_shell becomes:
appium --allow-insecure=uiautomator2:adb_shell
A wildcard form, --allow-insecure=*:adb_shell, is also accepted.
Session listing moved
GET /sessions is replaced by GET /appium/sessions, behind a session_discovery feature flag.
Capabilities
POST /session now accepts capabilities only. The old desiredCapabilities and requiredCapabilities keys are gone, so client code still building a plain desired-capabilities dictionary needs updating to an Options object.
What does an example Appium 2.x Test look like?
An Appium 2 test looks very similar to an Appium 1 test, with the necessary changes required. In case you want to run on TestingBot, you specifically need to take the capabilities into consideration.
Please see the example below for an example Appium 2 test, written in Python.
from appium import webdriver
from appium.options.ios import XCUITestOptions
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
options = XCUITestOptions().load_capabilities({
"platformName": "iOS",
"appium:deviceName": "iPhone XR",
"appium:version": "16.3",
"appium:app": "https://testingbot.com/appium/sample.ipa",
"appium:realDevice": True,
})
driver = webdriver.Remote("https://key:secret@hub.testingbot.com/wd/hub", options=options)
inputA = WebDriverWait(driver, 30).until(
EC.element_to_be_clickable((AppiumBy.ACCESSIBILITY_ID, "inputA"))
)
inputA.send_keys("10")
inputB = WebDriverWait(driver, 30).until(
EC.element_to_be_clickable((AppiumBy.ACCESSIBILITY_ID, "inputB"))
)
inputB.send_keys("5")
driver.quit()
Using TestingBot to run automated tests with Appium 2.x
TestingBot offers a grid of both physical mobile devices, iOS simulators and Android emulators.
To run an Appium 2 test on TestingBot, please see our Appium Documentation with various code examples.
We also recommend reading our Appium 2 documentation, for some more information on how to run Appium 2 tests in the cloud.