
NO XCODE BUILDING.
xcodebuild has always been able to build for a device from the terminal. The part that used to send people back to the GUI was getting the build onto the phone. Xcode 15 shipped xcrun devicectl, Apple's CLI for talking to a paired device.
MOOD.
START HERE.
- iPhone has been opened in Xcode at least once, with automatic signing on.
- Developer Mode is on: Settings → Privacy & Security → Developer Mode
- The phone is connected (USB) and unlocked
FIND. LOCATE YOUR DEVICE
xcrun devicectl list devicesBUILD. CONNECT YOUR APP
xcodebuild -project YourApp.xcodeproj -scheme YourScheme \
-destination 'platform=iOS,name=Your iPhone Name' \
-configuration Debug buildUse the device's name (as shown by devicectl) or its identifier — both work as a -destination. Automatic signing handles the rest as long as Xcode has provisioned that device before.
CONFIRM. Find the built .app
xcodebuild -project YourApp.xcodeproj -scheme YourScheme \
-destination 'platform=iOS,name=Your iPhone Name' \
-showBuildSettings 2>/dev/null | grep -E "TARGET_BUILD_DIR|FULL_PRODUCT_NAME"INSTALL.
xcrun devicectl device install app --device <device-id> /path/to/YourApp.appLAUNCH.
xcrun devicectl device process launch --device <device-id> com.yourcompany.yourappONE SCRIPT. EVERY STEP.
Five commands is a lot to remember. This script runs the whole thing: it finds your connected iPhone, always builds fresh (so you never accidentally reinstall something stale), installs it, and force-relaunches the app so a change you just made actually shows up instead of a suspended old process masking it. No flags needed — it detects your project, scheme, and device, and asks if more than one is found. It’s a maintained, versioned tool, not a one-off snippet, so grab it from its GitHub release instead of retyping it.
curl -LO https://github.com/unparty-app/theunpartyunppp/releases/download/itd-v1.1.0/install-to-device.sh
chmod +x install-to-device.sh
./install-to-device.shWHY?
- Scalable use it for WORKFLOW, a git hook, or an agent that builds and installs on save
- Performant No GUI focus-stealing while you work in the terminal or another window
- Same commands work headless, over SSH, or from CI runners with a device attached
If three commands feels like two too many, ios-deploy (brew install ios-deploy) wraps build-install-launch-and-stream-logs into one call. devicectl is the Apple-supported path and doesn't need a third-party tool, so it's the one worth learning first.
“The GUI is a convenience, not a requirement.”
— unparty-app
