Case study: Taperlark
Sell a Mac App Outside the App Store: How We Built It
How we ship three notarized Mac apps outside the App Store with our own license server, Stripe checkout and Sparkle updates, all running on one small VPS.
Published
Taperlark is our own studio of three Mac apps sold outside the App Store. Each app is signed with Developer ID and notarized by Apple, checks out through Stripe's embedded Checkout, activates with our own license server, and updates through signed Sparkle feeds. One small VPS runs the site, licensing, downloads and analytics.
We built Taperlark to learn the full direct-distribution stack by shipping it, and to have Mac apps we control end to end. Everything below comes from the repository and the live site at taperlark.com.
What are the three apps?
| App | What it does | 1 Mac | 2 Macs | 3 Macs |
|---|---|---|---|---|
| Preen | A menu-bar camera preview for checking your framing before a call | $6.99 | $11.99 | $14.99 |
| Submix | Separate volume, mute and output routing for each Mac app | $7.99 | $12.99 | $17.99 |
| CoolCurve | Temperature monitoring and fan control for Apple silicon Macs | $9.99 | $15.99 | $19.99 |
One-time prices in USD, as shown on taperlark.com on September 26, 2026. Each license is a lifetime offer whose terms do not change after purchase. CoolCurve installs a signed privileged helper, registered through Apple's SMAppService, to control the fans.
Can you sell a Mac app outside the App Store?
Yes. Apple lets you distribute Mac apps directly, as long as they are signed with a Developer ID certificate and notarized. What the App Store would otherwise do for you, you now own: payments, license checks, updates and the download server. In return you get control over pricing and trials, a direct relationship with buyers, and room for things like CoolCurve's privileged helper.
How do we sign and notarize each release?
The release script does the same steps every time:
- Sign the app with a Developer ID Application certificate, Hardened Runtime and a secure timestamp.
- Build and sign the disk image.
- Submit it with
xcrun notarytool submit ... --wait, using credentials stored in a Keychain profile, never in the repo. - Staple the ticket with
xcrun stapler staple. - Verify the signature, runtime, timestamp, entitlements and notarization before anything is published.
Step 5 exists because a release that looks fine locally can still fail Gatekeeper on a customer's Mac. The pipeline refuses to publish until every check passes.
How do license keys work without user accounts?
We wrote the license server ourselves. Its design choices:
- Keys look like
MAC-XXXXXX-XXXXXX-XXXXXX-XXXXXX, from 18 random bytes. The server stores a SHA-256 hash for lookup and an AES-256-GCM encrypted copy, never the plain key. - Seats. Activating a key binds one Mac's random install ID, kept in the Keychain, to a seat. Licenses cover 1, 2 or 3 Macs.
- Leases. The server returns a lease signed with Ed25519. It lasts 30 days and the app refreshes it quietly. If the Mac is offline, a 7 day grace period keeps the app working.
- Trials are issued by the server for 7 days, so deleting preferences does not restart one.
- No passwords. Buyers manage their Macs through a one-time link sent to the purchase email.
The trade-off: we run and secure a service that a vendor could run for us. In return, the rules for trials, seats and offline use are exactly the ones we want.
How do payments work?
Checkout is Stripe's embedded Checkout inside the site, with promotion codes. A webhook verifies Stripe's signature, ignores events it has already processed, issues the license on a completed checkout, and handles refunds and disputes. In September we changed it to acknowledge subscription events it has no use for instead of failing on them.
Choosing Stripe directly means we handle sales tax ourselves. Merchant-of-record services such as Paddle and Lemon Squeezy take that on for you. For a client, that choice depends on where the buyers are and how much admin they want.
How do updates work outside the App Store?
What does it run on?
One Hetzner VPS with Docker Compose:
- Caddy for TLS, downloads and appcasts
- the Next.js website, storefront and license API
- Postgres 16, with encrypted backups
- self-hosted Umami analytics, served from the site's own domain
A self-hosted GitHub Actions runner on the same box runs the checks, and every deploy pings IndexNow so Bing picks up changes quickly.
How long did it take?
The first commit was on July 21, 2026. The storefront with embedded checkout and the notarization pipeline were running on the production server the next day. Blog and SEO foundations followed on July 23, email delivery and pricing changes in early August, and CoolCurve 1.0.4 on September 21. That is 181 commits over two months.
What have we learned so far?
The engineering was the easy half. Signing, licensing and updates work, and they are reusable for any Mac app we build for a client.
Distribution is the hard half. A new domain with no links does not get found by publishing articles. Our September content wave of 11 articles earned 4 impressions in its first two weeks. For Taperlark the next step is off-site: launch posts, directories and communities, not more pages. We wrote up the other side of that lesson in our openwhenitstime case study.
The store currently runs Stripe in test mode, so there are no sales numbers to report yet.
Frequently asked questions
Can you sell a Mac app outside the App Store?
Yes. Apple allows direct distribution of Mac apps. The app must be signed with a Developer ID certificate and notarized by Apple so Gatekeeper lets it open. You then handle payments, license keys and updates yourself or through a vendor.
Do I need to notarize a Mac app I sell myself?
Yes, in practice. We sign each app and the disk image with a Developer ID Application certificate and Hardened Runtime, submit the disk image with notarytool, wait for Apple's result, and staple the ticket so the app opens cleanly even offline.
How do license keys work for a Mac app without accounts?
In our setup the buyer gets a key by email. Activating it ties one Mac's random install ID to a seat and returns a signed lease that lasts 30 days, with 7 days of offline grace. Buyers manage their Macs through a one-time link sent to their purchase email, so there are no passwords.
How do Mac apps update outside the App Store?
With Sparkle. Each of our apps reads its own EdDSA-signed appcast from our download server. The signing key never leaves the release machine's Keychain, and a release fails its checks if anything about the feed is wrong.
Should I use Stripe, Paddle or Lemon Squeezy for a Mac app?
We use Stripe's embedded Checkout because we wanted the license server and checkout under our control. Paddle and Lemon Squeezy act as merchant of record and handle sales tax for you, which is less work. It is a trade between control and paperwork.