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 (with the semver range ^20.19.0 || ^22.12.0 || >=24.0.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:
*) prefix:
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 /sessionsendpoint is replaced withGET /appium/sessions(see the Removed Endpoints section) - The use of the new endpoint requires the
session_discoveryfeature 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 /sessionstoGET /appium/sessions - If you use Appium Inspector's Attach to Session feature, upgrade to version
2025.3.1or later - In both cases, ensure your Appium server is launched with the
session_discoveryfeature 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: alertexecute method -
mobile: acceptAlertexecute 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: backgroundAppexecute method
-
POST /session/:sessionId/appium/app/close- Moved to drivers:
-
mobile: terminateAppexecute method -
macos: terminateAppexecute method -
windows: closeAppexecute method
POST /session/:sessionId/appium/app/end_test_coverage-
mobile: shellexecute method
-
POST /session/:sessionId/appium/app/launch- Moved to drivers:
-
mobile: launchAppexecute method -
mobile: activateAppormobile: startActivityexecute methods -
macos: launchAppormacos: activateAppexecute methods -
windows: launchAppexecute method
POST /session/:sessionId/appium/app/reset-
mobile: clearAppexecute method 1
-
POST /session/:sessionId/appium/app/strings-
mobile: getAppStringsexecute method
-
GET /session/:sessionId/appium/device/app_state-
POST /session/:sessionId/appium/device/app_state -
mobile: queryAppStateexecute method -
macos: queryAppStateexecute method
-
GET /session/:sessionId/appium/device/current_activity-
mobile: getCurrentActivityexecute method
-
GET /session/:sessionId/appium/device/current_package-
mobile: getCurrentPackageexecute method
-
GET /session/:sessionId/appium/device/display_density-
mobile: getDisplayDensityexecute method
-
POST /session/:sessionId/appium/device/finger_printPOST /session/:sessionId/appium/device/get_clipboard- Moved to drivers:
-
mobile: getClipboardexecute method -
mobile: getPasteboardexecute method 1 -
windows: getClipboardexecute method
POST /session/:sessionId/appium/device/gsm_callPOST /session/:sessionId/appium/device/gsm_signalPOST /session/:sessionId/appium/device/gsm_voicePOST /session/:sessionId/appium/device/is_locked-
mobile: isLockedexecute method
-
POST /session/:sessionId/appium/device/keyevent-
mobile: keysexecute method (iPadOS only) -
mobile: pressKeyexecute method -
macos: keysexecute method -
windows: keysexecute method
-
POST /session/:sessionId/appium/device/lock-
mobile: lockexecute method
-
POST /session/:sessionId/appium/device/long_press_keycode-
mobile: pressKeyexecute method
-
POST /session/:sessionId/appium/device/network_speedPOST /session/:sessionId/appium/device/open_notifications-
mobile: statusBarexecute method -
mobile: openNotificationsexecute method
-
POST /session/:sessionId/appium/device/power_acPOST /session/:sessionId/appium/device/power_capacityPOST /session/:sessionId/appium/device/press_keycode-
mobile: keysexecute method (iPadOS only) -
mobile: pressKeyexecute method -
macos: keysexecute method -
windows: keysexecute method
-
POST /session/:sessionId/appium/device/send_smsPOST /session/:sessionId/appium/device/set_clipboard-
mobile: setClipboardexecute method -
mobile: setPasteboardexecute method 1 -
windows: setClipboardexecute method
-
POST /session/:sessionId/appium/device/shake-
mobile: shakeexecute method 1
-
POST /session/:sessionId/appium/device/start_activity-
mobile: startActivityexecute method
-
GET /session/:sessionId/appium/device/system_bars-
mobile: deviceScreenInfoexecute method -
mobile: getSystemBarsexecute method
-
POST /session/:sessionId/appium/device/toggle_airplane_mode-
mobile: setConnectivityexecute method
-
POST /session/:sessionId/appium/device/toggle_data-
mobile: setConnectivityexecute method
-
POST /session/:sessionId/appium/device/toggle_location_services-
mobile: toggleGpsexecute method
-
POST /session/:sessionId/appium/device/toggle_wifi-
mobile: setConnectivityexecute method
-
POST /session/:sessionId/appium/device/unlock-
mobile: unlockexecute 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: getPerformanceDataexecute method
-
POST /session/:sessionId/appium/performanceData/types-
mobile: getPerformanceDataTypesexecute method
-
POST /session/:sessionId/appium/receive_async_response-
POST /session/:sessionId/execute/async
-
POST /session/:sessionId/appium/simulator/toggle_touch_id_enrollment-
mobile: enrollBiometricexecute method 1
-
POST /session/:sessionId/appium/simulator/touch_id-
mobile: sendBiometricMatchexecute method 1
-
POST /session/:sessionId/appium/start_recording_screen- Moved to drivers:
-
mobile: startXCTestScreenRecordingexecute method -
mobile: startMediaProjectionRecordingexecute method -
macos: startRecordingScreenormacos: startNativeScreenRecordingexecute methods -
windows: startRecordingScreenexecute method
POST /session/:sessionId/appium/stop_recording_screen- Moved to drivers:
-
mobile: stopXCTestScreenRecordingexecute method -
mobile: stopMediaProjectionRecordingexecute method -
macos: stopRecordingScreenormacos: stopNativeScreenRecordingexecute methods -
windows: stopRecordingScreenexecute 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: keysexecute method
POST /session/:sessionId/buttonup- Moved to drivers:
- W3C Actions API (
pointerUp) -
windows: keysexecute 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: tapormobile: tapWithNumberOfTapsexecute methods -
mobile: clickGestureexecute method -
mobile: clickActionexecute method -
macos: click,macos: rightClick,macos: pressormacos: tapexecute methods -
windows: clickexecute method
POST /session/:sessionId/touch/doubleclick- W3C Actions API (
pointerDown&pointerUp)- Selenium-based clients can also use Double Click
-
mobile: doubleTapormobile: tapWithNumberOfTapsexecute methods -
mobile: doubleClickGestureexecute method -
mobile: clickActionexecute method -
macos: doubleClickormacos: doubleTapexecute methods -
windows: clickexecute method
- W3C Actions API (
POST /session/:sessionId/touch/down- Moved to drivers:
- W3C Actions API (
pointerDown) -
windows: keysexecute method
POST /session/:sessionId/touch/flick- Moved to drivers:
- W3C Actions API (
pointerDown,pointerMove&pointerUp) -
mobile: flingGestureexecute method
POST /session/:sessionId/touch/longclick- Moved to drivers:
- W3C Actions API (
pointerDown,pause&pointerUp) -
mobile: touchAndHoldexecute method -
mobile: longClickGestureexecute method -
mobile: clickActionexecute method -
macos: pressexecute method -
windows: clickexecute 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: scrollormobile: swipeexecute methods -
mobile: scrollGestureormobile: swipeGestureexecute methods -
mobile: swipeexecute method -
macos: scrollormacos: swipeexecute methods -
windows: scrollexecute method
- W3C Actions API (
POST /session/:sessionId/touch/up- Moved to drivers:
- W3C Actions API (
pointerUp) -
windows: keysexecute 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
-