Get started
Start here: your first Mac app, step by step
This is the path from "I have never shipped a Mac app" to "someone just paid for mine". It goes in stages, and each stage ends with something you can see working before you move on. You do not need an Apple account, a payment account or a server until the stage that says so.
Every stage has the same parts:
- Why — what the stage is for, in plain words.
- Do — the exact steps.
- Or ask your agent — the same thing as a prompt for Claude Code, Cursor
or Codex. The agent follows the recipes in
.claude/skills/and runs the checks for you. - Done when — how you know it worked.
Stuck anywhere? docs/troubleshooting.md has the common
errors and their fixes.
| Stage | What you get | Needs an account? |
|---|---|---|
| 1. Install the tools | A Mac ready to build | No |
| 2. See it running | The website and the app on your screen | No |
| 3. Make it yours | Your name everywhere | No |
| 4. Build your app | Your product inside the app | No |
| 5. Write your website | Your words, price and policies | No |
| 6. Put the website online | A live site on your domain | Vercel (free), a domain |
| 7. Get ready to sign | An app other Macs will open | Apple Developer Program |
| 8. Take payments | A working checkout and licence keys | Creem or Polar |
| 9. Ship your first version | A downloadable, notarized app | — |
| 10. Open for sale | Customers can buy | — |
Start stage 7's Apple enrolment early. Apple reviews new developer accounts, and that has taken anything from an hour to a week. Enrol while you work on stages 3–6, so it is not what you wait for at the end.
About scripts/doctor.sh and all those "todo" lines
scripts/doctor.sh tells you where your project is up to. On a fresh copy it
lists a lot of todo lines — signing keys, payment keys, a release. That
is normal. Most of them belong to stages 6–10. Each stage below says which
doctor lines it turns green; ignore the rest until you get there.
1. Install the tools
Why. Xcode builds the Mac app; Node and pnpm run the website; XcodeGen
creates the Xcode project from a small text file (mac/project.yml), so the
project itself is never committed and never has merge conflicts.
Do.
-
Install Xcode (version 16 or later) from the Mac App Store, open it once, and let it finish installing its components.
-
In Terminal:
brew install xcodegen node corepack enableNo Homebrew? Get it from brew.sh first.
Done when xcodegen --version and node --version (22 or later) both
print a version.
2. See it running
Why. Before you change anything, see the finished template work on your own Mac. If something is wrong with your setup, you find out now, not later.
Do.
-
The website:
cd site pnpm install pnpm devOpen http://localhost:3000. It is a complete sales site with placeholder text. Leave it running in its own Terminal tab.
-
The app, in a second Terminal tab from the repository's folder:
mac/scripts/bootstrap.sh open mac/App.xcodeprojIn Xcode press Run (⌘R). The app opens on its licence window — the screen your customers see before they paste a key.
-
See the licensed app: Product → Scheme → Edit Scheme… → Run → Arguments → +, type
-AppDebugLicense YES, close, and Run again. Now you see what a customer sees after activating. (This only works in Debug builds; a real release always asks for a key.)
Or ask your agent.
Help me run the website and the Mac app for the first time, and check my setup is right.
Done when the site is in your browser and the app window is on screen.
Doctor now shows xcode-project and site-deps as ok.
3. Make it yours
Why. The template is called by a placeholder name everywhere — the app, the site, the emails, the settings. One command renames all of it, and a check makes sure nothing was missed.
Decide first:
- The name of your app, as written ("Clip Stack").
- The domain it will live on (clipstack.app). You do not have to own it yet, but you should be able to buy it.
- Creem or Polar for payments. Both work the same way here; if unsure, choose Creem, the default.
The name and domain are hard to change after your first release. The app's identity on customers' Macs is made from them. Take a minute to be sure.
Or ask your agent (recommended):
Make this my product. It's called Clip Stack, the website is clipstack.app, I'm Jane Doe, and I want to sell it through Creem with a licence key. Then run doctor and tell me what's next.
Or do it by hand:
scripts/new-app.sh --name "Clip Stack" --domain clipstack.app \
--maker "Jane Doe" --payments creem --deliverable licence-key
You do not need an Apple Team ID yet; you add it in stage 7.
Done when the website at http://localhost:3000 (restart pnpm dev) and the
app (run it again in Xcode) both show your name. Doctor shows rename as
ok.
4. Build your app
Why. This is the part only you can do: what your app actually does. It goes into the main window, which today says "Your app goes here".
Do. Describe your app to your agent, one feature at a time. Small steps work best — each one is built, tested and checked before the next.
Ask your agent. Start with the main screen:
Replace the home screen with my app: [what it does, in two or three sentences]. Keep the Settings button.
Then add features one by one:
Add a feature: [describe one thing the app should do].
Add a new window for [what it shows].
Add a setting to [what the user can choose].
My app needs access to [files / the camera / the network]. Add the right permission safely.
Run the app in Xcode after each change and try it.
If you write code yourself: the logic goes in mac/App/Core/ (with tests),
the screens in mac/App/Screens/. After adding a new Swift file, run
mac/scripts/bootstrap.sh so Xcode sees it. mac/AGENTS.md explains the
patterns.
Done when your app does its main job in the window, and this passes:
scripts/verify.sh --quick
5. Write your website
Why. The site sells your app. It already has the structure — hero, features, pricing, FAQ, legal pages — and needs your words, your price and your details.
Ask your agent.
Rewrite the website for my app: [what it does, who it's for, why it's better]. Keep every claim true to what the app really does, and tell me what I should check.
Set the price to $[amount], one-time, for one Mac.
Fill in the legal details: I'm [name or company], based in [city, country]. Refunds within [14] days.
Or by hand — the files, each with comments explaining every field:
site/lib/site.ts— name, tagline, descriptions, links.site/lib/pricing.ts— the price.site/lib/legal.ts— who sells it, where, and the refund window.site/lib/features.tsandsite/lib/faqs.tsx— the features and the FAQ.site/public/app-icon.svg— your icon; thenswift scripts/make-icons.swiftmakes every size from it.
docs/new-project.md is the full checklist of everything
worth personalising.
Done when the site at http://localhost:3000 reads like your product, and
scripts/verify.sh --quick passes.
6. Put the website online
Why. Your customers need a real address to buy from, and the app needs it too: activation and updates go through your site.
Needs: a free Vercel account, your repository on GitHub, and your domain.
Do.
- Push your repository to GitHub (private is fine).
- In Vercel: Add New → Project, pick the repository, set Root Directory
to
siteand the Build Command topnpm run vercel-build. - In the project's Settings → Environment Variables, add
NEXT_PUBLIC_SITE_URL=https://clipstack.appfor Production (https, nowww, no slash at the end). - Deploy, then add your domain under Settings → Domains and follow Vercel's DNS instructions.
Or ask your agent.
Walk me through putting the website online on Vercel with my domain, one step at a time.
Done when your domain shows your site. Nothing is for sale yet — the page collects email addresses for a waitlist until stage 10.
7. Get ready to sign
Why. macOS only opens apps from the internet if Apple has checked them. Without that, a customer who downloads your app is told it is damaged and should be moved to the Bin — even though it works perfectly on your Mac. This stage sets up the one-time pieces that make your app trusted, and your updates safe.
Needs: the Apple Developer Program (a yearly fee). Enrol as an individual unless you already have a company with a D-U-N-S number.
Do — once, in this order. docs/releasing.md has each
step in detail:
-
Enrol and wait for Apple's approval.
-
Create a Developer ID certificate: Xcode → Settings → Accounts → your Apple ID → Manage Certificates → + → Developer ID Application. Then back it up (Keychain Access → export it with its private key as a
.p12file) somewhere safe. -
Add your Team ID to the project. Find it with:
security find-identity -v -p codesigning # the Team ID is in bracketsthen set
DEVELOPMENT_TEAMto it inmac/project.yml, and runmac/scripts/bootstrap.sh. (Or ask your agent: "Set my Apple Team ID to ABCDE12345.") -
Save your notarization password in the keychain and create your update signing keys — both are one command each, in
docs/releasing.mdunder "One-time setup".
Or ask your agent.
I'm enrolled in the Apple Developer Program. Walk me through the one-time release setup in docs/releasing.md, one step at a time, and check each one.
Done when doctor shows team, signing-identity, notary-profile,
sparkle-public-key and sparkle-private-key as ok (use
scripts/doctor.sh --online for the notary check).
8. Take payments
Why. Creem or Polar handles the checkout, the tax, the invoice and your customers' licence keys. Your site and app are already wired to them; this stage connects your account.
Do. Follow docs/go-live.md in test mode first — no real
money moves, and you can buy your own app with a test card:
- Create your account and a product for your app (with licence keys turned on).
- Put the test keys in Vercel's environment variables, as go-live lists them.
- Buy your own app with a test card: the receipt email arrives with a licence key, and the key activates the app.
- Refund it, and see the key stop working.
Or ask your agent.
Walk me through connecting payments in test mode, then a test purchase and a refund. Tell me exactly what to click in the dashboard.
Done when a test purchase gives you a key that activates your app, and a refund turns it off.
9. Ship your first version
Why. This builds the real thing: your app signed, checked by Apple, packed into a disk image your customers download, plus the update feed that future versions arrive through.
Try it first, with no accounts:
mac/scripts/build-dmg.sh --unsigned 1.0.0 1
It makes the disk image exactly as a release does, unsigned, so you can check how it looks.
Then the real release:
Ask your agent (recommended):
Ship version 1.0.0. Stop before publishing so I can check everything.
Or follow Doing a release in docs/releasing.md, by hand or
through GitHub Actions.
Done when the disk image opens on another Mac — a friend's is perfect — without any warning. That is the only real proof that Apple's check reaches a stranger's machine.
10. Open for sale
Why. Everything works; now let people buy.
Do.
-
Switch payments to live mode (the second half of
docs/go-live.md) and make one real purchase yourself, then refund it. -
Turn on sales:
Ask your agent.
Everything is tested. Turn on sales and deploy.
(It sets
onSaleto true insite/lib/launch.ts: the waitlist becomes a buy button, everywhere on the site at once.) -
Tell your waitlist:
cd site && pnpm broadcast on-salecreates a draft email in Resend for you to review and send.
Done when someone you don't know buys your app. 🎉
After your first sale
- Ship updates: "Ship version 1.1 with these changes: …" — your customers' apps offer the update themselves.
- Get found: "Write a blog post answering [a question your customers search for]."
- Get template improvements: "Apply the latest template updates from the changelog to my project."
- Grow:
docs/growing.md— live prices, more licence options, a database when you need one.
This page is docs/start-here.md in the repository, copied 2026-09-25.