Migrating to Appium 3
This document is a guide for those who are using Appium 2 and would like to upgrade to Appium 3. It contains a list of breaking changes, as well as suggestions for handling them.
While Appium 2 was a major overhaul of the entire Appium architecture, Appium 3 is a smaller upgrade with fewer breaking changes, which should result in a much simpler migration process.
Installation¶
The installation method for Appium 3 remains the same as for Appium 2. If you want to upgrade, you can simply install Appium 3 on top of your existing installation:
## Breaking Changes
Node 20+ Required¶
With Appium 2, the minimum required Node version was 14.17.0
. Support for Node 14 had already
ended before the release of Appium 2, which meant that even users on outdated Node versions were
able to use it.
Appium 3 drops support for outdated Node versions, and bumps the minimum required version to Node
20.19.0
, as well as the minimum npm
version to 10
.
Actions Needed
Upgrade Node.js to v20.19.0
or newer, and npm
to v10
or newer
Deprecated Endpoints Removed¶
Appium 3 removes many previously deprecated server endpoints. Some of these endpoints have now become specific to one or more drivers, while most others have direct or close-to-direct replacements in other endpoints. All removed endpoints, along with replacements (where applicable) are listed in the Removed Endpoints section.
Some W3C endpoints used in Appium also existed in the old JSONWP standard, but required different parameters. With Appium 2, both standards for these endpoints were supported. Appium 3 changes these endpoints by removing support for the JSONWP parameters, and only accepting the W3C parameters. These endpoints are listed in the Modified Endpoints section.
Actions Needed
Check your Appium client documentation for the affected methods, and adjust your code to use their replacements
Feature Flag Prefix Required¶
With Appium 2, it was possible to opt into certain insecure features on server
startup, which could be enabled using the --allow-insecure
or --relaxed-security
flags. Appium
2.13
added the ability to optionally provide a scope prefix to specific features, ensuring that
they would only be enabled for the specified driver (or all of them).
Appium 3 makes the scope prefix mandatory, and will throw an error if features are specified
without a scope. Note that the behavior of the --relaxed-security
flag remains unchanged.
Actions Needed
If you use the --allow-insecure
server flag, add a scope prefix before each feature name.
For example, if you use the UiAutomator2 adb_shell
feature, on Appium 2 you would enable it
like this:
appium --allow-insecure=adb_shell
On Appium 3, to ensure this feature is only activated for UiAutomator2, you can run it like so:
appium --allow-insecure=uiautomator2:adb_shell
Alternatively, if you wish to keep the Appium 2 behavior and enable the feature for all
drivers that support it, you can use the wildcard (*
) prefix:
appium --allow-insecure=*:adb_shell
Server-scope features like session_discovery
also require the wildcard prefix.
Session Discovery Requires Feature Flag¶
In Appium 2, it was possible to retrieve all active server sessions via the GET /sessions
endpoint. This information could then be used, for example, in Appium Inspector, in order to attach
to an existing session, instead of creating a new one.
Appium 3 makes two changes to the session discovery process:
- The
GET /sessions
endpoint is replaced withGET /appium/sessions
(see the Removed Endpoints section) - The use of the new endpoint requires the
session_discovery
feature flag
The return value of GET /appium/sessions
is largely identical to GET /sessions
, but additionally
includes the created
field for each session entry, indicating the session creation time as a Unix
timestamp. The rest of the result format remains unchanged.
To reduce migration efforts, the GET /appium/sessions
endpoint (locked behind the aforementioned
feature flag) is also available in Appium 2.19
, allowing you to adjust your code before upgrading
to Appium 3. As for Appium Inspector, support for this new endpoint is available starting from
version 2025.3.1
.
Actions Needed
* If your code uses session retrieval, change the endpoint from GET /sessions
to
GET /appium/sessions
* If you use Appium Inspector's Attach to Session feature, upgrade to version 2025.3.1
or later
* In both cases, ensure your Appium server is launched with the session_discovery
feature flag
Unzip Logic Removed¶
Appium 3 removes the custom unzip logic used when working with files like application packages. Such files are often only relevant to particular platforms, therefore the functionality for handling these operations has been moved to relevant drivers.
Actions Needed
Ensure you are using the most recent versions of your drivers
Express 5¶
Appium 3 upgrades the internally-used express
dependency from v4
to v5
. This should not
affect users who use Appium directly, but developers integrating parts of Appium into their own
projects may want to check the Express 5 Migration Guide.
Actions Needed
None! (hopefully)
Endpoint Changes¶
Removed¶
The following is a list of all the Appium server endpoints removed in Appium 3. For ease of migration, additional information is provided for each endpoint: drivers that still support the endpoint; suggested replacement endpoints, or, rarely, the lack of any available replacements.
Icons are used to indicate endpoint support in either certain drivers, or in the core Appium server (applicable to all drivers):
- - Appium server
- - XCUITest driver
- - UiAutomator2 driver
- - Espresso driver
- - Mac2 driver
- - Windows driver
GET /sessions
-
GET /appium/sessions
-
POST /session/:sessionId/accept_alert
-
POST /session/:sessionId/alert/accept
-
mobile: alert
execute method -
mobile: acceptAlert
execute method
-
GET /session/:sessionId/alert_text
-
GET /session/:sessionId/alert/text
-
POST /session/:sessionId/alert_text
-
POST /session/:sessionId/alert/text
-
POST /session/:sessionId/appium/app/background
-
mobile: backgroundApp
execute method
-
POST /session/:sessionId/appium/app/close
- Moved to drivers:
-
mobile: terminateApp
execute method -
macos: terminateApp
execute method -
windows: closeApp
execute method
POST /session/:sessionId/appium/app/end_test_coverage
-
mobile: shell
execute method
-
POST /session/:sessionId/appium/app/launch
- Moved to drivers:
-
mobile: launchApp
execute method -
mobile: activateApp
ormobile: startActivity
execute methods -
macos: launchApp
ormacos: activateApp
execute methods -
windows: launchApp
execute method
POST /session/:sessionId/appium/app/reset
-
mobile: clearApp
execute method 1
-
POST /session/:sessionId/appium/app/strings
-
mobile: getAppStrings
execute method
-
GET /session/:sessionId/appium/device/app_state
-
POST /session/:sessionId/appium/device/app_state
-
mobile: queryAppState
execute method -
macos: queryAppState
execute method
-
GET /session/:sessionId/appium/device/current_activity
-
mobile: getCurrentActivity
execute method
-
GET /session/:sessionId/appium/device/current_package
-
mobile: getCurrentPackage
execute method
-
GET /session/:sessionId/appium/device/display_density
-
mobile: getDisplayDensity
execute method
-
POST /session/:sessionId/appium/device/finger_print
POST /session/:sessionId/appium/device/get_clipboard
- Moved to drivers:
-
mobile: getClipboard
execute method -
mobile: getPasteboard
execute method 1 -
windows: getClipboard
execute method
POST /session/:sessionId/appium/device/gsm_call
POST /session/:sessionId/appium/device/gsm_signal
POST /session/:sessionId/appium/device/gsm_voice
POST /session/:sessionId/appium/device/is_locked
-
mobile: isLocked
execute method
-
POST /session/:sessionId/appium/device/keyevent
-
mobile: keys
execute method (iPadOS only) -
mobile: pressKey
execute method -
macos: keys
execute method -
windows: keys
execute method
-
POST /session/:sessionId/appium/device/lock
-
mobile: lock
execute method
-
POST /session/:sessionId/appium/device/long_press_keycode
-
mobile: pressKey
execute method
-
POST /session/:sessionId/appium/device/network_speed
POST /session/:sessionId/appium/device/open_notifications
-
mobile: statusBar
execute method -
mobile: openNotifications
execute method
-
POST /session/:sessionId/appium/device/power_ac
POST /session/:sessionId/appium/device/power_capacity
POST /session/:sessionId/appium/device/press_keycode
-
mobile: keys
execute method (iPadOS only) -
mobile: pressKey
execute method -
macos: keys
execute method -
windows: keys
execute method
-
POST /session/:sessionId/appium/device/send_sms
POST /session/:sessionId/appium/device/set_clipboard
-
mobile: setClipboard
execute method -
mobile: setPasteboard
execute method 1 -
windows: setClipboard
execute method
-
POST /session/:sessionId/appium/device/shake
-
mobile: shake
execute method 1
-
POST /session/:sessionId/appium/device/start_activity
-
mobile: startActivity
execute method
-
GET /session/:sessionId/appium/device/system_bars
-
mobile: deviceScreenInfo
execute method -
mobile: getSystemBars
execute method
-
POST /session/:sessionId/appium/device/toggle_airplane_mode
-
mobile: setConnectivity
execute method
-
POST /session/:sessionId/appium/device/toggle_data
-
mobile: setConnectivity
execute method
-
POST /session/:sessionId/appium/device/toggle_location_services
-
mobile: toggleGps
execute method
-
POST /session/:sessionId/appium/device/toggle_wifi
-
mobile: setConnectivity
execute method
-
POST /session/:sessionId/appium/device/unlock
-
mobile: unlock
execute method
-
POST /session/:sessionId/appium/element/:elementId/value
-
POST /session/:sessionId/element/:elementId/value
-
POST /session/:sessionId/appium/element/:elementId/replace_value
-
POST /session/:sessionId/element/:elementId/value
-
POST /session/:sessionId/appium/getPerformanceData
-
mobile: getPerformanceData
execute method
-
POST /session/:sessionId/appium/performanceData/types
-
mobile: getPerformanceDataTypes
execute method
-
POST /session/:sessionId/appium/receive_async_response
-
POST /session/:sessionId/execute/async
-
POST /session/:sessionId/appium/simulator/toggle_touch_id_enrollment
-
mobile: enrollBiometric
execute method 1
-
POST /session/:sessionId/appium/simulator/touch_id
-
mobile: sendBiometricMatch
execute method 1
-
POST /session/:sessionId/appium/start_recording_screen
- Moved to drivers:
-
mobile: startXCTestScreenRecording
execute method -
mobile: startMediaProjectionRecording
execute method -
macos: startRecordingScreen
ormacos: startNativeScreenRecording
execute methods -
windows: startRecordingScreen
execute method
POST /session/:sessionId/appium/stop_recording_screen
- Moved to drivers:
-
mobile: stopXCTestScreenRecording
execute method -
mobile: stopMediaProjectionRecording
execute method -
macos: stopRecordingScreen
ormacos: stopNativeScreenRecording
execute methods -
windows: stopRecordingScreen
execute method
GET /session/:sessionId/application_cache/status
- JSONWP protocol command with no direct replacement
POST /session/:sessionId/buttondown
- Moved to drivers:
- W3C Actions API (
pointerDown
) -
windows: keys
execute method
POST /session/:sessionId/buttonup
- Moved to drivers:
- W3C Actions API (
pointerUp
) -
windows: keys
execute method
POST /session/:sessionId/click
- Moved to drivers:
- W3C Actions API (
pointerDown
&pointerUp
)
POST /session/:sessionId/dismiss_alert
-
POST /session/:sessionId/alert/dismiss
-
POST /session/:sessionId/doubleclick
- Moved to drivers:
- W3C Actions API (
pointerDown
&pointerUp
)
POST /session/:sessionId/element/active
-
GET /session/:sessionId/element/active
-
GET /session/:sessionId/element/:elementId/equals/:otherId
- Moved to drivers:
GET /session/:sessionId/element/:elementId/location
- Moved to drivers:
-
GET /session/:sessionId/element/:elementId/rect
GET /session/:sessionId/element/:elementId/location_in_view
- Moved to drivers:
GET /session/:sessionId/element/:elementId/pageIndex
- MJSONWP protocol command with no direct replacement
GET /session/:sessionId/element/:elementId/size
- Moved to drivers:
-
GET /session/:sessionId/element/:elementId/rect
POST /session/:sessionId/element/:elementId/submit
- JSONWP protocol command with no direct replacement
POST /session/:sessionId/execute
-
POST /session/:sessionId/execute/sync
-
POST /session/:sessionId/execute_async
-
POST /session/:sessionId/execute/async
-
POST /session/:sessionId/keys
- Moved to drivers:
- W3C Actions API (
keyDown
&keyUp
)- Selenium-based clients can also use Send Keys
GET /session/:sessionId/local_storage
- JSONWP protocol command with no direct replacement
POST /session/:sessionId/local_storage
- JSONWP protocol command with no direct replacement
DELETE /session/:sessionId/local_storage
- JSONWP protocol command with no direct replacement
GET /session/:sessionId/local_storage/key/:key
- JSONWP protocol command with no direct replacement
DELETE /session/:sessionId/local_storage/key/:key
- JSONWP protocol command with no direct replacement
GET /session/:sessionId/local_storage/size
- JSONWP protocol command with no direct replacement
POST /session/:sessionId/log
-
POST /session/:sessionId/se/log
-
GET /session/:sessionId/log/types
-
GET /session/:sessionId/se/log/types
-
POST /session/:sessionId/moveto
- W3C Actions API (
pointerMove
)- Selenium-based clients can also use Move by Offset
- W3C Actions API (
GET /session/:sessionId/screenshot/:elementId
-
GET /session/:sessionId/element/:elementId/screenshot
-
GET /session/:sessionId/session_storage
- JSONWP protocol command with no direct replacement
POST /session/:sessionId/session_storage
- JSONWP protocol command with no direct replacement
DELETE /session/:sessionId/session_storage
- JSONWP protocol command with no direct replacement
GET /session/:sessionId/session_storage/key/:key
- JSONWP protocol command with no direct replacement
DELETE /session/:sessionId/session_storage/key/:key
- JSONWP protocol command with no direct replacement
GET /session/:sessionId/session_storage/size
- JSONWP protocol command with no direct replacement
POST /session/:sessionId/timeouts/async_script
-
POST /session/:sessionId/timeouts
-
POST /session/:sessionId/timeouts/implicit_wait
-
POST /session/:sessionId/timeouts
-
POST /session/:sessionId/touch/click
- Moved to drivers:
- W3C Actions API (
pointerDown
&pointerUp
)- Selenium-based clients can also use Click and Release
-
mobile: tap
ormobile: tapWithNumberOfTaps
execute methods -
mobile: clickGesture
execute method -
mobile: clickAction
execute method -
macos: click
,macos: rightClick
,macos: press
ormacos: tap
execute methods -
windows: click
execute method
POST /session/:sessionId/touch/doubleclick
- W3C Actions API (
pointerDown
&pointerUp
)- Selenium-based clients can also use Double Click
-
mobile: doubleTap
ormobile: tapWithNumberOfTaps
execute methods -
mobile: doubleClickGesture
execute method -
mobile: clickAction
execute method -
macos: doubleClick
ormacos: doubleTap
execute methods -
windows: click
execute method
- W3C Actions API (
POST /session/:sessionId/touch/down
- Moved to drivers:
- W3C Actions API (
pointerDown
) -
windows: keys
execute method
POST /session/:sessionId/touch/flick
- Moved to drivers:
- W3C Actions API (
pointerDown
,pointerMove
&pointerUp
) -
mobile: flingGesture
execute method
POST /session/:sessionId/touch/longclick
- Moved to drivers:
- W3C Actions API (
pointerDown
,pause
&pointerUp
) -
mobile: touchAndHold
execute method -
mobile: longClickGesture
execute method -
mobile: clickAction
execute method -
macos: press
execute method -
windows: click
execute method
POST /session/:sessionId/touch/multi/perform
- Moved to drivers:
-
POST /session/:sessionId/actions
POST /session/:sessionId/touch/move
- Moved to drivers:
- W3C Actions API (
pointerMove
)- Selenium-based clients can also use Move by Offset
POST /session/:sessionId/touch/perform
- Moved to drivers:
-
POST /session/:sessionId/actions
POST /session/:sessionId/touch/scroll
- W3C Actions API (
pointerDown
,pointerMove
&pointerUp
) -
mobile: scroll
ormobile: swipe
execute methods -
mobile: scrollGesture
ormobile: swipeGesture
execute methods -
mobile: swipe
execute method -
macos: scroll
ormacos: swipe
execute methods -
windows: scroll
execute method
- W3C Actions API (
POST /session/:sessionId/touch/up
- Moved to drivers:
- W3C Actions API (
pointerUp
) -
windows: keys
execute method
GET /session/:sessionId/window_handle
- Moved to drivers:
-
GET /session/:sessionId/window
GET /session/:sessionId/window_handles
- Moved to drivers:
-
GET /session/:sessionId/window/handles
GET /session/:sessionId/window/handle
-
GET /session/:sessionId/window
-
POST /session/:sessionId/window/:windowhandle/maximize
-
POST /session/:sessionId/window/maximize
- Only supported for the current window
-
GET /session/:sessionId/window/:windowhandle/position
-
GET /session/:sessionId/window/rect
- Only supported for the current window
-
POST /session/:sessionId/window/:windowhandle/position
-
POST /session/:sessionId/window/rect
- Only supported for the current window
-
GET /session/:sessionId/window/:windowhandle/size
- Moved to drivers:
-
GET /session/:sessionId/window/rect
- Only supported for the current window
Modified¶
The following are all endpoints modified in Appium 3, by removing handling for old or unused parameters (note that no new parameters have been added). Each endpoint lists the parameters it no longer accepts, as well as the parameters it continues to accept in Appium 3.
POST /session
-
desiredCapabilities
,requiredCapabilities
-
capabilities
-
POST /session/:sessionId/alert/text
-
value
-
text
-
GET /session/:sessionId/appium/device/system_time
-
format
- None
-
POST /session/:sessionId/element/:elementId/value
-
value
-
text
-
POST /session/:sessionId/timeouts
-
type
,ms
-
script
,pageLoad
,implicit
-
POST /session/:sessionId/window
-
name
-
handle
-