NoMacSign in
← Blog

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

LayerWindows / LinuxmacOS + Xcode
Swift language and compilerOfficially supportedSupported
Swift Package ManagerSupportedSupported
Portable Foundation codeDepends on API availabilitySupported
SwiftUI and UIKitNot available for iOS compilationSupported
iOS SDK and SimulatorNot availableSupported
App Store archive and signingNot available nativelySupported

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_project after every relevant source change.
  • ·build with workflow=smoke for compilation feedback.
  • ·status until the build reaches a final state.
  • ·get_failure when it fails, before changing code.
  • ·workflow=release only 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.

Ship it without a Mac.

Signed builds, TestFlight and App Store submission — driven by your agent.

Start shipping