Skip to content
Tech News
← Back to articles

Building and shipping Mac and iOS apps without opening Xcode

read original more articles

Lately, I’ve heard several Apple related podcasters talk about how bad Xcode is, and how Apple needs to make vibe-coding Mac and iOS apps better by making Xcode less inscrutable. They’re not wrong, but also I don’t understand why they’re even opening Xcode in the first place. With a little bit of pre-work, you can vibe code Mac and iOS apps to your heart’s content without looking at Xcode anymore.

And if you’re ever in doubt about how to make any of the following work, point Claude Code or your LLM coding tool of choice to this blog post, and let it figure it out. That’s literally its job, figuring out things you don’t want to have to.

TL;DR

Xcode.app must be installed, but it never has to be open. xcodebuild , notarytool , stapler , and devicectl all live inside Xcode and run fine from a shell.

, , , and all live inside Xcode and run fine from a shell. A few one-time steps do need the GUI (or an interactive terminal): sign into your Apple ID, create a Developer ID certificate, store a notarization password. After that, builds and deploys are fully headless.

(or an interactive terminal): sign into your Apple ID, create a Developer ID certificate, store a notarization password. After that, builds and deploys are fully headless. The Mac app ships via one script — scripts/release.sh — which you write once. It runs the whole chain: archive → Developer ID sign → notarize → staple → install to /Applications .

— — which you write once. It runs the whole chain: archive → Developer ID sign → notarize → staple → install to . Signing is certificate-and-keychain based. The signing key lives in the login keychain; xcodebuild finds it automatically. No secrets in the repo.

The one-time setup is the only part with any friction, so let’s get it out of the way first.

Install Xcode

You do have to have Xcode installed, there’s no getting around that, because build depends on tools that live inside Xcode.app.

... continue reading