Flutter iOS Development on Windows and Linux Without a Mac · NoMac

Build a Flutter iOS app on Windows or Linux

Develop Flutter on Windows or Linux, prepare a reproducible iOS project, build it remotely with Xcode, and send the signed app to TestFlight.

September 9, 2026 ·10 min read

You can develop a Flutter app on Windows or Linux and publish its iOS version without owning a Mac. Dart, widgets, tests, Android, web, and desktop targets run locally. The iOS Runner, native plugins, Xcode archive, code signing, and TestFlight release still need macOS.

Keep the complete Flutter application in a reproducible repository, put it on a cloud Mac, and let your agent reconstruct the iOS configuration there before building.

Send the Flutter application root containing both pubspec.yaml and ios/ to the Mac. Sending only the iOS directory omits the Dart packages and Flutter tooling inputs required to create the native build.

What works outside macOS?

Task Windows / Linux Remote Mac
Write Dart and Flutter widgets Yes Can build again
Run analysis and Flutter tests Yes Optional repeat
Run Android, web, or supported desktop target Yes Not required
Compile the iOS Runner and native plugins No Xcode Required
Run iOS Simulator No Yes
Sign and upload to TestFlight Can request Required

Flutter's official iOS setup guide installs Xcode before running on an iOS device or Simulator. Flutter shares a large part of the application, but its iOS output is still a native Apple target.

Prepare a complete Flutter repository

MyApp/
├── pubspec.yaml
├── pubspec.lock
├── .fvmrc                 # recommended exact Flutter version
├── lib/
├── test/
├── assets/
└── ios/
    ├── Runner.xcodeproj/
    ├── Runner.xcworkspace/
    ├── Runner/
    └── Podfile            # when the project still uses CocoaPods

Flutter is not preinstalled on a NoMac Mac, so the agent installs the pinned version first. Cloning the Flutter SDK into ~/drive, which is kept between sessions, means the next session skips that download. An exact project pin gives the clearest repeatability. The declared Dart and Flutter constraints must agree with the lockfile.

Check the iOS Runner before the first build

Set a unique bundle identifier matching the App Store Connect record. Confirm the product name, deployment target, version, build number, app icon, launch screen, supported orientations, capabilities, and permission descriptions.

Flutter plugins can bring native Swift, Objective-C, CocoaPods, or Swift Package Manager dependencies into the build. A package that works on Android can still require a newer iOS target or an Apple capability.

Run the fast checks locally

flutter pub get
flutter analyze
flutter test

Also run the app on an Android device, web browser, or supported desktop target when useful. These checks validate Dart and much of the shared interface. They do not prove that the iOS Runner, native plugins, Pods, entitlements, or signing are correct.

Connect Flutter to a cloud Mac

From the directory containing pubspec.yaml, install the CLI and authenticate:

npm install -g @nomac/cli
nomac login

Register npx @nomac/cli mcp with your agent. It starts a Mac with start_mac and clones the repository into ~/drive/src, or runs nomac sync . from the same root. On the Mac it runs flutter pub get, which regenerates the iOS build configuration, and builds.

The Flutter-to-TestFlight loop

1. Compile the iOS target

On the Mac, build for the Simulator without signing. This needs no Apple account, and the agent reads the first actionable error straight from the output.

flutter pub get
flutter build ios --simulator

2. Fix the owning layer

3. Build the signed release

After the compile check passes, the agent calls set_up_signing (CLI: nomac sign). It registers the bundle ID, makes the App Store profiles, and returns the exact Flutter commands for a signed build. Run them, then send the .ipa with send_to_testflight (CLI: nomac testflight). Apple processes it, usually in 5 to 15 minutes, then install it through TestFlight.

4. Test the iOS-specific behavior

Verify startup, text input, safe areas, scrolling, back gestures, dark mode, Dynamic Type, permission dialogs, notifications, deep links, backgrounding, restoration, and every native plugin. Compare the behavior with Android only where the product should genuinely match.

Important limitation: Flutter add-to-app

This guide covers a complete Flutter application with its iOS Runner. Flutter add-to-app modules embedded inside a separate native host need a project-specific integration. A full Mac can build them, but the steps follow the host app: build the Flutter module the way the host expects, then build and sign the host project.

Flutter's current iOS add-to-app documentation also shows that this is a separate integration flow, now moving toward Swift Package Manager for current Flutter releases.

Common mistakes

Publish the Flutter app

Inspect privacy manifests and data collection for every plugin, prepare screenshots from the processed TestFlight build, and verify the App Store metadata. Run review_lint on the App Store record. Provide review credentials if the app has login. Stage the exact build with publish and require human confirmation before submission.

Follow the complete 2026 publishing guide for the store steps. Windows or Linux remains the Flutter development machine; the cloud Mac performs the Apple-specific part.