Build a macOS app without owning a Mac
Native Mac apps need macOS to compile and to run. How to build, unit test, launch headless and package a macOS app from Windows or Linux on a cloud Mac.
· 8 min read
Need a Mac for this? NoMac gives your agent full macOS with Xcode, from $9.99 a month, billed by the second. Start now →
Most “without a Mac” guides are about iPhone apps. Building a native macOS app without a Mac is a slightly different problem. The compile step is the same: you need Xcode, which needs macOS. But the app you build also only runs on macOS, so you cannot even launch the result on your own machine. Everything happens on the Mac.
The good news: a macOS app is easier to test remotely than an iPhone app in one way. There is no simulator in between. The cloud Mac runs your app directly.
What you can do locally
- ·Write SwiftUI and AppKit code in any editor, with an AI agent if you like.
- ·Put business logic in a Swift package without Apple frameworks, and test it with the Linux Swift toolchain. See SwiftUI on Windows and Linux.
- ·Manage the project with Git, and keep the Xcode project or package manifest in it.
Anything that imports SwiftUI, AppKit or other Apple frameworks has to compile on macOS.
Build it on a cloud Mac
nomac start --json nomac sync . nomac ssh -- xcodebuild -scheme MyMacApp \ -destination 'platform=macOS' -derivedDataPath build build
For a pure Swift package with an executable target, swift build works too. Unsigned local builds need no Apple Developer account.
Test it
nomac ssh -- xcodebuild -scheme MyMacApp -destination 'platform=macOS' test
Unit tests run directly on the VM. UI tests for macOS apps need a logged-in graphical session with the right permissions, which headless environments may not grant, so start with unit tests and treat UI tests as an experiment on any headless Mac.
Launch it and look at it
You can start the built app on the Mac and capture the screen to check that it renders:
nomac ssh -- open build/Build/Products/Debug/MyMacApp.app nomac ssh -- mkdir -p shots nomac ssh -- screencapture -x shots/main.png nomac pull ./shots --from shots
Whether screencapture succeeds depends on the session having a display and screen recording permission. If it returns an error or a blank image, rely on unit tests, snapshot tests that render views to images inside the test process, and logs instead.
Package it
There are three ways to ship a Mac app, and they need different things:
- ·Unsigned zip for yourself or testers: works, but Gatekeeper warns everyone who opens it. Fine for a quick internal check, bad for users.
- ·Developer ID signed and notarized, distributed from your site: needs an Apple Developer membership, a Developer ID certificate on the Mac for the signing step, and
xcrun notarytoolwith an App Store Connect API key. All of it runs from the command line. - ·Mac App Store: needs a Mac App Store distribution certificate and provisioning profile, an archive, and an upload to App Store Connect, then TestFlight for Mac and App Review.
# Developer ID flow, once signing is set up on the session xcodebuild -scheme MyMacApp -configuration Release archive -archivePath build/MyMacApp.xcarchive xcodebuild -exportArchive -archivePath build/MyMacApp.xcarchive \ -exportOptionsPlist ExportOptions.plist -exportPath build/export ditto -c -k --keepParent build/export/MyMacApp.app build/MyMacApp.zip xcrun notarytool submit build/MyMacApp.zip --key AuthKey.p8 \ --key-id KEYID --issuer ISSUER --wait xcrun stapler staple build/export/MyMacApp.app
Signing means sending a certificate to the Mac. On a VM that is deleted at stop, that is a manageable risk if you handle it carefully. Read signing secrets on a rented Mac first.
What you give up without a Mac of your own
- ·Feel. You cannot use the app day to day. Find a tester with a Mac, or use a remote-desktop Mac rental for occasional hands-on sessions.
- ·Hardware integrations. Cameras, Bluetooth and USB devices are not available on a cloud VM.
- ·Performance truth. A VM is not a customer's MacBook. Profile on real hardware before you trust numbers.
For everything else, a cloud Mac gives you the full build, test and release pipeline for a Mac app from Windows or Linux. To let an agent run it, see give Claude Code a Mac.