Why Not Just Use xcodebuild?
You can. We do.
FlowDeck calls xcodebuild under the hood. Same build system, same schemes, same signing. The difference is everything around it.
The Problem Isn't xcodebuild
It's that xcodebuild is just one piece.
A build needs:
xcodebuildto compilexcrun simctlto manage simulatorsxcrun devicectlto manage physical devicesxcrun simctl launchto run the appxcrun simctl spawn ... log streamto see logs- Shell scripts to glue it together
- Regex to parse the output
That's not a workflow. That's archaeology.
Side by Side
| What You're Doing | Apple's Tools | FlowDeck |
|---|---|---|
| Target a simulator | xcrun simctl list, find UDID, construct platform=iOS Simulator,name=iPhone 16,OS=18.0 |
-S "iPhone 16" |
| Target a device | xcrun devicectl list, copy UDID, hope the syntax is right |
-D "iPhone" |
| Build for Mac | Figure out which destination string works this year | -D "My Mac" |
| Build and run | xcodebuild, then simctl install, then simctl launch |
flowdeck run |
| Stream logs | xcrun simctl spawn booted log stream --predicate 'subsystem contains...' |
flowdeck logs |
| Run one test | -only-testing:MyAppTests/LoginTests/testValidLogin |
--only LoginTests/testValidLogin |
| Skip slow tests | -skip-testing:MyAppTests/SlowTests |
--skip SlowTests |
| Discover tests | Build first, then parse output | flowdeck test discover |
| Find schemes | xcodebuild -list (2-5 second wait) |
flowdeck context (instant) |
| Clean everything | xcodebuild clean + rm -rf ~/Library/Developer/Xcode/DerivedData + maybe Xcode cache too |
flowdeck clean --all |
| Parse output | Regex. Hope. Pray. | --json |
8 Commands. Not 84.
Apple's tooling:
xcodebuildxcrunsimctldevicectlinstrumentsxcode-selectios-deployxcresulttoolxctracealtoolnotarytool...
FlowDeck:
contextbuildruntestcleansimulatordevicelogs
Learn once. Use everywhere.
Output You Can Actually Use
CompileSwift normal arm64 /Users/dev/MyApp/ContentView.swift (in target 'MyApp' from project 'MyApp')
cd /Users/dev/MyApp
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file /Users/dev/MyApp/ContentView.swift ...
/Users/dev/MyApp/ContentView.swift:42:15: error: cannot convert value of type 'String' to expected argument type 'Int'
return someFunction(value)
^~~~~
Plus 400 more lines.
{
"type": "build_started",
"scheme": "MyApp",
"destination": "iPhone 16"
}
{
"type": "error",
"file": "ContentView.swift",
"line": 42,
"column": 15,
"message": "cannot convert 'String' to 'Int'"
}
{
"type": "build_completed",
"success": false,
"duration": 8.2
}
Your CI parses it. Your AI agent understands it. You see what matters.
Speed Where It Counts
| Operation | xcodebuild | FlowDeck |
|---|---|---|
| Scheme discovery | 2-5 seconds | Instant |
| Simulator lookup | Spawns process, parses text | Native, cached |
| Test discovery | Requires build | AST parsing, no build |
These aren't benchmarks for marketing. These are the operations you run fifty times a day.
What Doesn't Change
.xcodeproj and .xcworkspace files
FlowDeck reads your project. It doesn't own it.
Need more proof?
Give it a go.
curl -sSL https://flowdeck.studio/install.sh | sh