Monetization · Paywalls

RevenueCat, Adapty, or rolling your own

Every time I start a subscription app, someone asks the same question on day one: do we wire up RevenueCat, or do we just talk to StoreKit ourselves? After shipping both ways more than once, I've stopped treating it as a matter of taste.

It's a build-vs-buy decision, and like every build-vs-buy decision it has a right answer that depends entirely on your situation. A paywall SDK — RevenueCat, Adapty, Apphud, take your pick — solves a real, annoying problem. It also takes a cut and plants a dependency squarely in your purchase path. The trick is knowing which of those facts dominates for the app in front of you.

What the SDK actually buys you

Strip away the marketing and a paywall SDK is doing a handful of concrete jobs. The first is receipt validation and entitlement state: it watches transactions, validates them server-side, and gives you a single boolean — is this user a subscriber right now? — that's correct across reinstalls, refunds, billing retries, and the family-sharing edge cases you forgot existed. That sounds small until you've written it yourself.

On top of that sit the things you'd otherwise build a backend for. Remote paywall configuration means you can change prices, copy, and layout without shipping a build. A/B testing lets you run two paywalls against each other and read the conversion difference without rolling your own assignment and stats. There's a dashboard with MRR, churn, trial conversion, and cohort charts that your non-engineer co-founder can actually read. And there are webhooks so your own backend hears about renewals and cancellations without polling Apple.

The quietly biggest win is cross-platform. The moment you have an Android app too, "is this user subscribed?" stops being a StoreKit question and becomes a question that spans two stores and two billing systems. An SDK gives you one entitlement model over both. Rolling that yourself is a project, not a feature.

What it costs you

The obvious cost is money. The pricing has shifted over the years, but the shape is the same: free under some monthly revenue threshold, then either a percentage of tracked revenue or a flat platform fee above it. On a meaningful revenue base that's a real line item — a slice of your subscription income, on top of Apple's own 15–30%, going to a third party forever.

The cost engineers underrate is the dependency in your purchase path. This SDK now sits between your user and their money. Its outages, its migration deadlines, its breaking changes, its bugs — they're now yours too, in the most revenue-critical flow you own. I've never had a catastrophic failure here, but I have spent a sprint on a forced major-version upgrade that bought my users nothing. That's the tax you don't see in the pricing page.

There's also lock-in. Your entitlement truth lives in someone else's system, and your historical subscriber data is shaped by their model. Leaving is possible — these vendors aren't hostile about it — but it's migration work, and the longer you stay the more there is to move.

How StoreKit 2 changed the math

A lot of the case for an SDK was built in the StoreKit 1 era, when receipt validation genuinely was a miserable, error-prone slog of parsing a base64 blob and talking to Apple's verification endpoint. StoreKit 2 narrowed that gap considerably.

With StoreKit 2 you get transactions as typed Swift values, cryptographically signed with JWS so you can verify them on-device or on your server without the old round-trip. Transaction.currentEntitlements hands you the set of things the user currently owns. Transaction.updates is an async sequence that delivers renewals and revocations as they happen. For a single non-consumable or one straightforward subscription, that's most of what the SDK's validation layer was doing for you — now in the platform, for free.

What StoreKit 2 still doesn't give you is the rest of the package: the cross-platform entitlement model, the remote paywall config, the A/B framework, the dashboard, the webhooks to your backend. So the gap narrowed for the validation piece specifically, which happens to be the piece people were most afraid of. If validation was your only reason to reach for an SDK, that reason is a lot weaker in 2025 than it was in 2020.

The comparison, dimension by dimension

Here's how the two paths stack up across the things that actually decide it. "Roll your own" assumes StoreKit 2 and a modest backend of your own.

DimensionPaywall SDKRoll your own
Receipt validationDone, server-side, edge cases handledStoreKit 2 gets you most of the way; edge cases are on you
Paywall A/B testingBuilt in, no-code, results in the dashboardYou build assignment, logging, and the stats
Analytics & chartsMRR, churn, cohorts out of the boxWhatever you wire into your own analytics
Cross-platformOne entitlement model over iOS + AndroidA real project per extra platform
CostRevenue share or platform fee, foreverEngineering time up front, near-zero after
Lock-inEntitlement truth lives in their systemYou own every byte of it

Read the table and the pattern is obvious: the SDK wins on everything that's a recurring product capability, and loses on cost and control. That's the whole trade in one grid.

The cut is buying iteration speed, not code

The revenue share feels like you're paying for receipt validation you could write in a weekend. You're not — that part's nearly commoditized now. What the cut actually buys is the ability to change a price or test a paywall this afternoon, without a build and without an engineer. If your monetization is static, you're paying for a treadmill you never step on. If you're iterating on pricing weekly, that same fee is the cheapest growth lever you have.

When to roll your own

Rolling your own wins in a recognizable shape of app. One simple product — a single subscription or a lifetime unlock — where there's almost no entitlement complexity to manage. iOS only, so the cross-platform argument never applies. A team that isn't going to run experiments, because the price is the price and the paywall is the paywall. And cases where privacy or control is a selling point, where shipping a third-party SDK in the purchase path is something you'd rather not explain to users or an enterprise buyer.

If you already validate locally with StoreKit 2 and your entitlement logic fits on one screen, an SDK is largely solving problems you don't have. I've shipped utility apps with exactly one non-consumable where adding RevenueCat would have been pure overhead — a dependency and a future migration in exchange for a dashboard nobody would open.

When the SDK clearly wins

The SDK earns its cut just as clearly in the opposite shape. Lots of experiments: if growth depends on testing paywalls, prices, and trial lengths, the A/B and remote-config machinery pays for itself in the first test you'd otherwise have hand-rolled. A non-iOS platform: the second you ship Android, a unified entitlement model is worth real money. And a team that lives in the dashboard — a founder, a growth marketer, a finance person who needs MRR and churn without filing a ticket — gets a tool they'll use daily, which is its own kind of velocity.

Note that none of these is "validation is too hard." They're all about iteration, reach, and visibility. That's the modern case for a paywall SDK, and it's a strong one for the apps it fits.

My heuristic

Here's the rule I actually use. If monetization is a feature, roll your own. If monetization is the business, buy the SDK.

A paid utility where the subscription is a quiet line at the bottom of the settings screen — that's a feature, and StoreKit 2 covers it. An app whose entire growth model is converting free users on a paywall you'll tune for years — that's the business, and you want the best monetization tooling you can get, cut and all. When I'm genuinely on the fence, I lean toward the SDK early and keep my own entitlement check as a thin layer on top, so leaving later is a migration and not a rewrite.

What I've stopped doing is treating this as a point of principle. There's a tribe that insists real engineers don't pay a vendor to talk to StoreKit, and another that can't imagine shipping without the dashboard. Both are arguing identity, not economics. It's a build-vs-buy call — run the numbers for the app you're actually shipping, weigh the cut against the iteration speed it buys, and pick the answer that fits. The right choice for my next app might be the opposite of the last one, and that's exactly as it should be.

← All writing