SwiftUI development on Windows and Linux
Write and organize SwiftUI source outside macOS, test portable Swift logic locally, then compile the Apple interface remotely and install it through TestFlight.
· 9 min read
You can write and maintain SwiftUI source on Windows or Linux, but you cannot compile the SwiftUI iPhone target there. Swift is a cross-platform language; SwiftUI is an Apple interface framework delivered with Apple's SDKs and built by Xcode on macOS.
A useful no-Mac workflow keeps portable Swift logic testable outside macOS, sends the complete iOS project to a cloud Mac for compilation, and uses TestFlight for real-device UI feedback.
Installing Swift on Windows or Linux lets you compile supported Swift code. It does not install SwiftUI, UIKit, the iOS SDK, SwiftUI previews, or the iOS Simulator.
Swift and SwiftUI are different layers
| Layer | Windows / Linux | macOS + Xcode |
|---|---|---|
| Swift language and compiler | Officially supported | Supported |
| Swift Package Manager | Supported | Supported |
| Portable Foundation code | Depends on API availability | Supported |
| SwiftUI and UIKit | Not available for iOS compilation | Supported |
| iOS SDK and Simulator | Not available | Supported |
| App Store archive and signing | Not available natively | Supported |
Swift.org publishes toolchains for Windows and Linux. Apple describes SwiftUI as the framework for building interfaces across Apple platforms in its SwiftUI technology overview. Those facts are compatible: the language travels farther than every framework.
Design the repository around that boundary
Separate the code by responsibility. The exact shape depends on the app, but this layout makes the boundary visible:
MyApp/ ├── MyApp.xcodeproj/ # iOS targets and build settings ├── App/ # SwiftUI app entry and navigation ├── Features/ # SwiftUI screens and feature state ├── Packages/ │ └── AppCore/ # portable models, validation, parsing, rules │ ├── Package.swift │ ├── Sources/ │ └── Tests/ ├── Assets.xcassets/ └── PrivacyInfo.xcprivacy
The portable package should not import SwiftUI or UIKit. Keep values, validation, search, calculations, and other domain rules there. The app target owns views, navigation, Apple persistence adapters, notifications, permissions, and platform-specific behavior.
Do not distort the architecture just to make every line compile on Linux. Some code is correctly Apple-specific. The goal is a useful test boundary, not pretending the iPhone UI is portable.
Choose an editor
- ·VS Code with the official Swift extension is strong for Swift Package Manager projects, navigation, refactoring, tests, and debugging.
- ·Cursor adds a repository-aware coding agent and MCP tools on Windows and Linux.
- ·Claude Code, Codex, or Grok Build can work from the terminal, maintain project files, and act on remote build failures.
- ·Any LSP editor can use SourceKit-LSP for supported Swift source.
The official Swift extension guide says its primary project models are Swift Package Manager and projects that generate a compile_commands.json. Do not expect full Xcode project indexing outside Xcode.
Start with a complete iOS project
The cloud Mac needs more than a Swift file. Your repository must include a valid .xcodeproj or .xcworkspace, a discoverable application scheme, build settings, app assets, and source membership. You can begin from a known template, an exported native project, or have a capable coding agent generate and maintain the project.
Decide these values early:
- ·Product name and unique reverse-domain bundle identifier.
- ·Minimum supported iOS version.
- ·App capabilities and their entitlements.
- ·Local storage and network boundaries.
- ·Permissions and user-facing purpose strings.
- ·Version and monotonically increasing build number.
Test portable Swift locally
From the portable package directory, the normal loop is:
swift build swift test
These commands can prove the core package under the local platform. They cannot prove that the iOS app target imports the package correctly, that every API exists at the deployment target, or that a SwiftUI view compiles. The Xcode build remains authoritative.
Compile SwiftUI on a cloud Mac
Connect NoMac from the machine containing the repository:
npx @nomac/cli login
Register npx @nomac/cli mcp with your agent, then use this sequence:
- ·
push_projectafter every relevant source change. - ·
buildwithworkflow=smokefor compilation feedback. - ·
statusuntil the build reaches a final state. - ·
get_failurewhen it fails, before changing code. - ·
workflow=releaseonly for a coherent TestFlight candidate.
Run the portable Swift tests first. Push the complete project and start a NoMac smoke build. If SwiftUI compilation fails, retrieve the exact diagnostic, identify the file and deployment requirement, and make the smallest correction. Do not replace the native UI with a web view.
Replace previews with deliberate feedback
Without a Mac, you do not have local SwiftUI previews. Compensate by keeping views small, using standard controls, and describing visual states explicitly. Every important screen should have known loading, empty, content, error, permission-denied, and large-text states.
Use TestFlight for feature checkpoints. Capture the build number and screenshots. Report the exact device state and action to the agent. A good report says, “On build 18, after denying notifications, the empty screen still shows Enable Alerts as active.”
Common SwiftUI mistakes outside Xcode
- ·Invented APIs. A generated modifier may look plausible but not exist in the SDK. Let the remote compiler settle the question.
- ·Wrong availability. New APIs need an appropriate deployment target or an availability fallback.
- ·Missing target membership. A file can exist in Git without belonging to the Xcode target.
- ·Unshared scheme. A clean build service cannot use a scheme stored only in one developer's local Xcode data.
- ·Preview-only confidence. Even on a Mac, a preview is not a complete device test.
When you should use a remote interactive Mac
Choose one when the work depends on rapid visual iteration, complex animations, Instruments, debugger breakpoints, UI automation, or many simulator configurations. A managed build is better for repeatable compilation and distribution; it is not an interactive design canvas.
For most small agent-built apps, the practical split is enough: test the core locally, compile SwiftUI remotely, test complete features on an iPhone, then publish through the 2026 App Store workflow.