Build and ship a Flutter iOS app without a Mac
Flutter runs well on Windows and Linux, until you need iOS. On a PC, Flutter does not even offer the iOS build command. You need macOS for that step, either on a rented Mac or a CI runner. We ran the whole route on October 19, 2026, with Flutter 3.47.7 and Xcode 26.6.
What works on Windows and Linux
Your Dart code, widget tests and Android builds all work on a PC. In our test, a new app passed flutter test on GitHub's Windows Server 2025 and Ubuntu 24.04 runners. The Ubuntu job also built a debug Android APK. Hot reload on an Android emulator works the same way.
Then we asked both machines for an iOS build. Flutter hides the iOS commands on any system that is not macOS. Both runners printed the same line:
Could not find a subcommand named "ios" for "flutter build".
Its list of build targets offered apk, appbundle, web and the desktop target of the host. There was no ios and no ipa.
What needs macOS
- flutter build ios and flutter build ipa. Flutter's release guide says Xcode is required, and you must use a device running macOS.
- Native packages. Since Flutter 3.44, plugins come in through Swift Package Manager. Flutter falls back to CocoaPods for plugins that do not support it yet. Both run inside the Xcode build.
- The iOS Simulator. It ships with Xcode, so it only runs on a Mac. See the iOS Simulator on Windows for the options.
- Signing and upload. Certificates and profiles are made and used on the Mac.
Set up Flutter on a rented Mac
A MacRun Mac comes with Xcode 27.1 and the iOS 27.1 simulator. Xcode 26.6 is installed too. Flutter is not preinstalled, so you add it. You have admin rights and Homebrew. This one command worked in our test and installed Flutter 3.47.7 in under a minute:
brew install --cask flutter flutter --version
Flutter's own docs use a download instead. You unzip the macOS bundle into a folder such as ~/develop, then add this line to ~/.zprofile:
export PATH="$HOME/develop/flutter/bin:$PATH"
Next comes the Xcode setup from Flutter's iOS page. It selects Xcode, runs the first launch tasks, and shows the license. Then it checks the iOS platform and simulator runtimes:
sudo sh -c 'xcode-select -s /Applications/Xcode-27.1.app/Contents/Developer && xcodebuild -runFirstLaunch' sudo xcodebuild -license xcodebuild -downloadPlatform iOS flutter doctor -v
On a MacRun Mac, Xcode 27.1 is at /Applications/Xcode-27.1.app and is already selected. Xcode 26.6 is at /Applications/Xcode.app. On another Mac, use the path that ls -d /Applications/Xcode*.app prints. On our runner, flutter doctor gave Xcode a green check and found CocoaPods 1.17.0. It flagged the Android licenses, which do not matter for iOS.
Build and run in the Simulator
Clone your repo, run flutter pub get, and build for the Simulator. In our test the app had one plugin, shared_preferences. No Pods folder appeared, so Flutter used Swift Package Manager.
flutter build ios --simulator xcrun simctl list devices available xcrun simctl boot "iPhone Duo" xcrun simctl install booted build/ios/iphonesimulator/Runner.app xcrun simctl launch booted com.example.demo
Use a device name from the list and your own bundle ID. On MacRun, the iOS 27.1 runtime brings the iPhone Duo device. Over screen sharing you can also use flutter run with a booted simulator for hot reload. From Windows, follow Xcode from Windows to see the Mac's screen.
The workflow we ran on GitHub Actions
This is the macOS job from our test. It creates an app, adds a plugin, and builds for the Simulator. It then installs and opens the app, and builds and archives a release with no signing.
name: flutter-guide
on: workflow_dispatch
jobs:
macos:
runs-on: macos-26
steps:
- uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- run: xcodebuild -version && sw_vers
- run: flutter doctor -v
- run: flutter create demo
- run: flutter pub add shared_preferences
working-directory: demo
- name: Simulator build
run: time flutter build ios --simulator
working-directory: demo
- name: Install and launch in the Simulator
run: |
xcrun simctl list devices available | grep -i iphone | head -5
UDID=$(xcrun simctl list devices available -j | python3 -c "import json,sys; d=json.load(sys.stdin)['devices']; print(next(x['udid'] for k,v in d.items() if 'iOS' in k for x in v if x['name'].startswith('iPhone')))")
echo "UDID=$UDID"
xcrun simctl boot "$UDID"
xcrun simctl bootstatus "$UDID"
xcrun simctl install booted build/ios/iphonesimulator/Runner.app
xcrun simctl launch booted com.example.demo
sleep 10
xcrun simctl io booted screenshot shot.png
ls -la shot.png
working-directory: demo
- name: Release build, no signing
run: time flutter build ios --release --no-codesign
working-directory: demo
- name: Archive, no signing
run: time flutter build ipa --no-codesign
working-directory: demoThe whole job took 5 minutes 39 seconds. These lines come from its log:
[✓] Xcode - develop for iOS and macOS (Xcode 26.6) [5.9s] ✓ Built build/ios/iphonesimulator/Runner.app com.example.demo: 14546 ✓ Built build/ios/iphoneos/Runner.app (14.6MB) ✓ Built build/ios/archive/Runner.xcarchive (170.4MB) Codesigning disabled with --no-codesign, skipping IPA.
The Simulator build took 48 seconds. The release build took 1 minute 14 seconds, and the archive 45 seconds. The last line matters. With no signing, Flutter stops at the archive. A real .ipa needs your Apple team.
Ship to TestFlight
You need the Apple Developer Program, which is 99 USD a year. Create the app in App Store Connect from any browser. On the Mac, open ios/Runner.xcworkspace in Xcode once. Pick your team under Signing and Capabilities. Then build the .ipa:
flutter build ipa --build-name 1.0.0 --build-number 2
Flutter writes the archive to build/ios/archive and the .ipa to build/ios/ipa. Upload it with Transporter, or with this line from Flutter's docs and an App Store Connect API key:
xcrun altool --upload-app --type ios -f build/ios/ipa/*.ipa \ --apiKey your_api_key --apiIssuer your_issuer_id
We could not run the signed steps on CI, since our test had no Apple account. They come from Flutter's release guide. To test on your own iPhone, install the build from TestFlight. A remote Mac cannot see a phone plugged into your PC. Our publishing guide covers API keys and review.
Who should not rent a Mac for this
If you only need an .ipa, a cloud build may be enough. Flutter's release guide has a section on Codemagic. Codemagic personal accounts include 500 macOS build minutes a month for free. A GitHub Actions macOS runner runs the workflow above, billed by the minute. If you ship every week for years, a used Mac mini can cost less over time.
A rented Mac fits when you need to see the app. That means the Simulator, Xcode's signing screens, or a crash in the debugger. A MacRun day pass is $15 for a dedicated M6 Mac mini, and a week is $59. You pay once and nothing renews. The Mac is wiped at the end, so push your code and save your .ipa first.
Frequently asked questions
Can Flutter build iOS on Windows?
+
No. On Windows and Linux, Flutter does not offer flutter build ios or flutter build ipa at all. Flutter's release guide says you must use a device running macOS. A rented Mac or a macOS CI runner covers that step.
Can I run my Flutter app in the iOS Simulator from Windows?
+
Not on Windows itself, because the Simulator ships with Xcode. You can build on a remote Mac and view its Simulator over screen sharing. We installed and launched a Flutter app with xcrun simctl on a macOS runner.
Does Flutter still need CocoaPods for iOS?
+
Less often. Since Flutter 3.44, Swift Package Manager is on by default for iOS. Flutter falls back to CocoaPods for plugins that do not support it yet. Flutter says the CocoaPods registry becomes read-only on December 2, 2026.
Can I build a Flutter .ipa without signing?
+
You can archive without signing. In our test, flutter build ipa --no-codesign made a 170.4 MB .xcarchive and then said it was skipping the IPA. A real .ipa for TestFlight needs your Apple Developer team.
How long does a Flutter iOS build take on a Mac?
+
On GitHub's macos-26 runner, a Simulator build of a new app with one plugin took 48 seconds. An unsigned release build took 1 minute 14 seconds. Larger apps take longer.
Is Flutter installed on a MacRun Mac?
+
No. Xcode 27.1, Xcode 26.6 and the iOS 27.1 simulator are installed. You have admin rights and Homebrew, and brew install --cask flutter took under a minute in our test.