CLI reference
Every xcross command and flag for Flutter and Compose Multiplatform, taken from the CLI source.
xcross <command> [subcommand] [options]. Add --help at any level. -v / --verbose works everywhere.
ImportantComing from 1.x? In 2.0 xcross doctor became flutter doctor / compose doctor, xcross clean became flutter clean / compose clean / sdk clean, and auth clear became auth clean.
At a glance
setup · sdk install · sdk clean · auth · config · updatetunnel · tunnel --wififlutter run · flutter build · flutter doctor · flutter clean · idecompose setup · compose build · compose run · compose doctor · compose clean| Command | Does |
|---|---|
setup | Install or verify host tools |
sdk install <Xcode.xip> | Extract the Darwin SDK |
sdk clean | Remove the installed Darwin SDK |
auth / auth clean | Save or remove Apple credentials |
config / show / validate | Edit, print, check configuration |
tunnel [--wifi] | Mount DDI + start the iOS 17+ RSD tunnel |
flutter run / build | Run or build a Flutter app |
flutter doctor / compose doctor | Read-only readiness check for that framework |
flutter clean / compose clean | Clear this project’s xcross caches |
compose setup / build / run | Set up, build or run a Compose app |
ide vscode / idea | Wire up IDE debugging (Flutter) |
update | Verified self-update |
completion | Print a bash/zsh completion script |
setup
xcross setup
Idempotent. On Linux it installs LLVM, device utilities and pymobiledevice3 through apt, dnf or pacman (Homebrew on macOS), and needs Swift on PATH first. On Windows it runs a setup script for winget, Scoop or Chocolatey (or direct.ps1, which downloads signed vendor installers), asking before each package: VS Build Tools, Swift, LLVM, Python.
Before any script runs, xcross prints its name, source URL and SHA-256 and waits for y.
| Flag | |
|---|---|
--manager <name> | Windows: pick winget, scoop, choco or direct (asks when several are installed) |
-y, --yes | Accept the script and every installer prompt |
--refresh-script | Re-download a configured setup script without running it |
What setup does on Linux
- Detects
apt-get,dnforpacman, prompting if several exist. - Installs
clang,lld,llvm, Python,usbmuxd,usbipand Swift’s build dependencies. - Probes
ld64.lldfor the broken selector-stub bug and symlinks a newerld64.lld-<N>into/usr/local/binif needed. - Installs
pymobiledevice3throughpipx.
What setup does on Windows
winget | scoop | choco | direct | |
|---|---|---|---|---|
| VS Build Tools | Microsoft.VisualStudio.2022.BuildTools | vendor installer | visualstudio2022buildtools | vendor installer |
| Swift | Swift.Toolchain | main/swift | vendor installer | vendor installer |
| LLVM | LLVM.LLVM | main/llvm | llvm | GitHub release |
| Python | Python.Python.3.13 | main/python | python313 | python.org |
Vendor installers only run with a valid Microsoft or Apple Authenticode signature. Downloads are checked against the published SHA-256. Pin versions for direct with XCROSS_SWIFT_VERSION, XCROSS_LLVM_VERSION, XCROSS_PYTHON_VERSION. When another LLVM is already on PATH, the pinned LLVM goes into XCROSS_LLVM_DIR. Chocolatey needs an Administrator PowerShell, Scoop a normal one.
sdk install
xcross sdk install <path-to-Xcode.xip> # or an Xcode.app on macOS
xcross sdk clean # remove it, plus leftover backup/staging copies
No flags. Replaces any previous SDK. See Darwin SDK.
auth
xcross auth --apple-id you@example.com
xcross auth --issuer-id <uuid> --key-id <id> --private-key AuthKey.p8
xcross auth clean
| Flag | |
|---|---|
--apple-id, --password | Apple ID login (prompted if omitted) |
--issuer-id, --key-id, --private-key | App Store Connect API key |
--adi-library-dir | ADI libraries for hosts other than x64 / ARM64 |
auth clean deletes the saved key, the Apple ID session and every certificate, key and profile xcross minted. The old auth clear spelling fails with a pointer to the new one.
doctor
xcross flutter doctor # in a Flutter project
xcross compose doctor # in a Gradle project
Read-only. Each checks only what its own framework needs: the project, its toolchain, the Darwin SDK, then the shared deployment checks (device tools, auth, connected iOS versions). Output is grouped into project, toolchain and deployment sections, each headed by its worst status. Missing project or device context is a warning. A failed requirement exits non-zero.
compose doctor lists every Compose requirement on its own row (Kotlin/Native, JDK 21+, Gradle, swiftc, clang, ld64.lld). A missing Kotlin/Native download is only a warning, since the first build fetches it.
tunnel
xcross tunnel # USB
xcross tunnel --wifi # pair / reconnect wirelessly
Needs sudo or Administrator. Run once per device reconnect. See Run over Wi-Fi.
Device selection
Shared by flutter run and compose run.
| Flag | |
|---|---|
-d, --device-id | Device id or name |
-u, --udid | Exact UDID, wins over -d |
--usb / --wifi | Search one transport only |
--device-connection | attached · wireless · both (default) |
flutter
xcross flutter run
xcross flutter run -u <UDID> -D API_URL=https://staging.example.com
xcross flutter build -i --flavor staging -t lib/main_staging.dart
| Flag | run | build | |
|---|---|---|---|
-t, --target | ✓ | ✓ | Entry point (default lib/main.dart) |
--flavor | ✓ | ✓ | App flavor |
-D, --dart-define | ✓ | ✓ | KEY=VALUE, repeatable |
--dart-define-from-file | ✓ | ✓ | .json / .env, repeatable |
--[no-]pub | ✓ | ✓ | flutter pub get first (on) |
--route | ✓ | Initial route | |
-a, --dart-entrypoint-args | ✓ | Args for main() | |
--build-name, --build-number | ✓ | Version strings | |
-i, --ipa | ✓ | Output .ipa instead of .app | |
--target-platform | ✓ | iphone (default) or simulator (arm64 Simulator app, verified on macOS ARM64, no --ipa) | |
--[no-]tree-shake-icons | ✓ | Tree shake icon fonts (on) |
Always debug (JIT). Shaders are compiled with the host impellerc, like flutter build. flutter dap is internal, spawned by your IDE.
App ID on first device run
The first device build of an app asks which App ID to register, and saves the answer so it can be committed:
XCR-<TEAM>.com.example.appcom.example.app# pubspec.yaml (Compose: xcross_project.yaml)
xcross:
bundle_id: original # or prefixed
Precedence: XCROSS_BUNDLE_ID=original|prefixed for one run, then the saved bundle_id, then an App ID the team already has, then the question. CI and IDE sessions can’t be asked: they use the saved value, else fall back to prefixed.
compose
xcross compose setup
xcross compose build --ipa
xcross compose run --watch
| Command | Flags |
|---|---|
compose setup | --check (verify only), --force (refresh Kotlin/Native cache) |
compose build | --configuration debug|release, --bundle-id, --app-name, --ipa, --target-platform iphone|simulator (simulator needs a macOS host) |
compose run | device flags, --bundle-id, -a app args, --watch |
compose doctor | read-only readiness check |
compose clean | clear this project’s xcross build output and Kotlin/Native caches |
ide
xcross ide vscode
xcross ide idea
No flags. See IDE integration.
config
xcross config # TUI editor
xcross config show
xcross config validate
update
xcross update
| Flag | |
|---|---|
--check | Report the target version only |
--ref <ref> | Install a tag, branch or commit |
--force | Reinstall even if current |
-y, --yes | Skip the confirmation |
clean
xcross flutter clean # this project's native asset + SwiftPM caches (device and simulator)
xcross compose clean # this project's xcross build output + Kotlin/Native caches
xcross sdk clean # the installed Darwin SDK
Shared caches and unrelated build output are left alone.
completion
xcross completion >> ~/.zshrc
Environment
| Variable | |
|---|---|
XCROSS_OFFLINE=1 | Skip Apple and sign from the cache. See offline |
XCROSS_BUNDLE_ID | original or prefixed for this run |
XCROSS_APP_GROUP | App Group to use with an API key |
XCROSS_CONFIG | Path to a config file |
XCROSS_NO_UPDATE_CHECK=1 | Silence the new-release hint |