Open-source project
appium/appium-xcuitest-driver avatar
appium/appium-xcuitest-driver

appium-xcuitest-driver is the Appium backend for Apple platform apps

Appium driver for iOS/tvOS/watchOS, backed by Apple XCTest

905 stars473 forksTypeScriptApache-2.0

At a glance

What is it?
The XCUITest driver is the piece that lets Appium automate native and hybrid applications on iOS, iPadOS, tvOS and watchOS, using Apple's XCTest framework as the backend. It is a Node package inside the Appium driver ecosystem, it requires Appium 3 from version 10 onwards, and it is released on a very fast cadence.
Who is it for?
Adopt appium-xcuitest-driver if your team already runs Appium and needs to cover Apple platform applications through one client API, and if you have a macOS build host ready, because the XCTest backend ties the driver to Apple's toolchain.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One driver for four Apple platforms, with a hard Appium 3 requirement

Automating an iOS application from a test script is not a solved problem on its own. The application runs in its own process on a device or a Simulator, and something has to sit between your test and the application to translate a request like tap this element into the work the platform expects. The XCUITest driver is that something, for the Appium world.

The scope is stated plainly in the README: it is an Appium driver for automating native and hybrid applications on iOS, iPadOS, tvOS and watchOS, with the watchOS support marked as Simulator only. The word hybrid matters, since it covers applications that embed a web view alongside native controls, and the repository topics list ipados, tvos and watchos alongside ios, xctest and webdriveragent.

There is one constraint that shapes every upgrade decision: since major version 10.0.0, the driver is only compatible with Appium 3. That is not a soft recommendation in a changelog line, it is an IMPORTANT callout in the README itself. A team on Appium 2 cannot use a current release of this driver, which means an Appium major upgrade and a driver major upgrade are the same project. Anyone evaluating this driver is really evaluating a coupling between two version numbers.

A TypeScript package that compiles to an ES module

The repository is a normal Node package, and the manifest tells you how it is built and shipped. The identity is short:

json
  "name": "appium-xcuitest-driver",
  "version": "12.19.1",

The description in the manifest is precise about the mechanism: Appium driver for iOS using XCUITest for backend, and the keyword list includes webdriveragent, which is the Appium XCUITest backend project name.

Two packaging choices are worth knowing about. The package is an ES module, declared with a type of module, and the entry point is the compiled output rather than the source: the main field points at ./build/lib/index.js and the types field at ./build/lib/index.d.ts, with an exports map that exposes the same paths. The published files list shows what actually ships: the lib directory, the scripts directory with the CI folder excluded, the build/lib directory, and then CHANGELOG.md and LICENSE. The bin field is empty, because the driver exposes no command line of its own, it is loaded by the Appium server.

That last point is the one that changes how you install it. This is not a tool you run against a device. It is a plugin that the Appium server loads, which is why the documentation site, and specifically its getting started page, is the place the README points a new user rather than a command line.

Compiling, linting and testing are all npm script entries

The build toolchain is deliberately plain. The TypeScript compiler does the compiling, and the manifest scripts show it:

json
    "build": "tsc -b",
    "clean": "npm run build -- --clean",
    "dev": "npm run build -- --watch",

Linting and formatting are handled by oxlint and oxfmt, each pointed at its own configuration file in the repository root, with separate fix and check variants for both:

json
    "lint": "oxlint -c oxlint.config.mjs .",
    "lint:fix": "oxlint -c oxlint.config.mjs --fix .",
    "format": "oxfmt -c oxfmt.config.mjs .",
    "format:check": "oxfmt -c oxfmt.config.mjs --check .",

The unit tests run on the Node built in test runner rather than on an external framework, and the command shows the runner flags that matter, including source map support, module mocks, a forced exit and a sixty second timeout:

json
    "test": "node --enable-source-maps --experimental-test-module-mocks --test --test-force-exit --test-timeout=60000 \"./build/test/unit/**/*.spec.js\"",

The test path is the compiled unit test output under build/test/unit, which means the tests run against the same files that ship, not against the TypeScript sources.

For a contributor, the loop is therefore short: build with tsc, run the unit tests on the compiled output, and lint with oxlint. A separate script builds the documentation with appium-docs, and another publishes it to a docs-site branch with an alias for the latest version.

Releases land within days of each other, and the changelog is the record

The release history is the most striking operational fact about this repository. The three most recent releases are v12.19.1 on 2026-10-19, v12.19.0 on 2026-10-18 and v12.18.3 on 2026-10-18, and the last push to the repository was on 2026-10-20. The version in package.json matches the newest tag, at 12.19.1.

That cadence has consequences for how you consume the driver. Patch releases arriving within a day of each other mean the release notes are the only practical way to know what changed between the version you pinned last week and the one your build system pulls today. The CHANGELOG.md at the repository root is linked from the README, and the release process is driven by a release.config.mjs file in the root, with a publish workflow whose badge sits at the top of the README.

The same speed makes pinning less optional than it sounds. A driver that changes several times a week will interact with the Appium server version, with the WebDriverAgent backend it depends on, and with the iOS runtime versions in ways that a changelog entry may mention in a single line. Teams that upgrade a mobile pipeline weekly will see this driver in their dependency resolution constantly, and teams that upgrade rarely will find that the gap between their pinned version and the current one grows quickly.

Documentation is versioned in the same way, since the publish script builds and deploys the docs with an alias for the latest release, so the site you read corresponds to the release you are on rather than always to the newest one.

The boundaries: Simulator only for watchOS, and a macOS toolchain

The driver has hard edges, and they are not all in the same direction.

The first is the backend itself. The driver automates applications through Apple's XCTest framework, which means the machinery that does the work belongs to Apple's toolchain rather than to this repository. Anything that stands between your test host and a working XCTest runtime, such as a missing simulator image or a device trust problem, surfaces as a failure in the driver even though the code in this repository is fine. The webdriveragent keyword in the package manifest points at the Appium backend project that handles that side, and the repository itself does not contain it.

The second is the watchOS restriction, which the README marks as Simulator only. If you need watchOS automation against a physical device, this driver does not cover it, and nothing in the repository suggests a plan to change that.

The third is the Appium 3 coupling, already described. It constrains the driver itself and the projects that depend on it.

A fourth boundary is worth naming because it is easy to misread: the README does not document a rollback path, a compatibility matrix across iOS versions, or a supported device list. The compatibility guidance lives in the hosted documentation. If your plan depends on a specific OS version combination, that check belongs in the driver documentation and in the changelog, not in the repository itself.

Where the alternative is XCUITest without the driver layer

The natural alternative is to skip Appium and drive XCTest directly from Apple's own tooling, which is how the framework is used in its native form. The difference in approach is the layer in between.

With XCTest used directly, the test code lives in an Xcode test bundle, runs on Apple's test runner, and the object under test is reached through the framework's own APIs. There is no session, no WebDriver style request layer, and no separate server process to install and keep in step with the test code.

With the XCUITest driver, the test client speaks to an Appium server, which loads this driver, which then talks to the XCTest backend and returns page source, element locators and command results in the form the Appium protocol defines. The benefit is that one client API can drive the Apple platforms alongside other platforms handled by other Appium drivers, and that the test client is not tied to an Xcode project layout. The cost is the extra moving parts: the Appium server, the driver version, the backend version, and the Appium 3 requirement, none of which exist in the direct route.

The choice therefore follows the shape of your suite. A single platform application tested by one team is a reasonable candidate for the direct route, because fewer moving parts is worth more than protocol uniformity. A suite that already speaks to Appium, or that spans Apple platforms and Android, gets a lot from this driver because the client side stays the same across platforms.

Apache-2.0, a contributors list, and repository tooling you did not expect

The licence is Apache-2.0, recorded in the package manifest and in the LICENSE file at the repository root, and the author field reads Appium Contributors. Apache-2.0 carries an explicit patent grant and a notice requirement, which is a common choice for infrastructure that other vendors embed in their own products, though the specifics of your use are a matter for your own review.

The repository layout shows a modern toolchain in more ways than the build scripts. There are editor and assistant directories at the root, including .claude/, .cursor/ and .codegraph/, alongside an .mcp.json file, a .vscode/ directory, an .editorconfig file and an .npmrc. In other words, the project ships configuration for AI coding assistants and for MCP as part of the source tree, which is a deliberate choice by the maintainers and tells you something about how contributions are expected to be made. The documentation build is driven by mkdocs through the appium-docs tooling, and the repository also holds a scripts/ directory that is published to npm while its CI subfolder is explicitly excluded from the package.

There is no dedicated contributor guide in the file listing, and no CODEOWNERS or governance file at the root, so the practical guidance for contributing comes from the GitHub issue tracker and the project's discussion channels rather than from a document in the tree.

Editorial conclusion

Adopt appium-xcuitest-driver if your team already runs Appium and needs to cover Apple platform applications through one client API, and if you have a macOS build host ready, because the XCTest backend ties the driver to Apple's toolchain. Do not adopt it for a cross platform suite that includes Android without checking the Appium 3 requirement, since the driver has been Appium 3 only since major version 10.0.0, and do not adopt it as a generic iOS test tool outside Appium, since the value it adds is the driver layer rather than XCTest itself. Before you start, read the getting started page in the driver documentation, confirm your Appium server is version 3 or newer, and check whether the watchOS target you care about is a Simulator, because that is the only watchOS configuration the driver covers.

Frequently asked questions

What does the Appium XCUITest driver support?

It automates native and hybrid applications on iOS, iPadOS, tvOS and watchOS, with watchOS supported for the Simulator only. The backend is Apple's XCTest framework, exposed through the Appium driver model.

Which version of Appium does appium-xcuitest-driver require?

Since major version 10.0.0, the driver is only compatible with Appium 3. The README marks this as important, so an Appium 2 server cannot run a current driver release.

How do I install and start using appium-xcuitest-driver?

The driver is loaded by the Appium server rather than run as a command, and it publishes no binary of its own, since the bin field in package.json is empty. The README points new users to the getting started page in the driver documentation for the setup steps.

How is the driver built and tested from source?

The build script is tsc -b, linting runs through oxlint with oxlint.config.mjs, and formatting through oxfmt with oxfmt.config.mjs. The unit tests run on the Node built in test runner against the compiled output under build/test/unit.

What licence does appium-xcuitest-driver use?

Apache-2.0, as recorded in the package.json manifest and in the LICENSE file at the repository root. The manifest lists the author as Appium Contributors.

Official sources

  1. appium/appium-xcuitest-driver on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/appium-appium-xcuitest-driver.svg)](https://hysenlabs.com/projects/appium-appium-xcuitest-driver)

Was this useful?