The 30-second answer
Five paywall archetypes cover most shipped iOS subscription apps in 2026: single product with free trial, tiered comparison, hard paywall on first launch, soft paywall feature gate, and free trial first. Annual plan default selected lifts annual share by 30 to 60 percent. A 7 day trial with explicit no payment language lifts trial start rate by 20 to 40 percent. Place the paywall after a clear value moment, not on first launch with no value shown.
Paywalls are the highest leverage screen in any subscription iOS app. A 5 percent conversion lift compounds into 50 percent more revenue over a year. This guide covers the five archetypes that work in 2026, with SwiftUI code for each, the conversion psychology behind why they work, the most common App Review rejection reasons, and how to A/B test without shipping app updates.
The Five Paywall Archetypes
| Archetype | Description | Best for |
|---|---|---|
| 1. Single Product | One plan, one price, optional free trial | Utilities, focused tools, minimum viable monetization |
| 2. Tiered Comparison | Monthly vs annual columns with savings badge | Established apps maximizing annual share |
| 3. Hard Paywall | No free tier, paywall on first launch | Premium content apps, high conviction value |
| 4. Soft Paywall | App is usable, premium features locked | Productivity, fitness, journaling |
| 5. Free Trial First | Trial starts automatically, paywall at trial end | High value subscription apps, post onboarding |
Archetype 1: Single Product Paywall
The simplest pattern. One product, one price, optional free trial. Used by Bear, Things, Tot, and many indie productivity apps.
struct SingleProductPaywall: View {
@Environment(SubscriptionStore.self) private var store
@Environment(\.dismiss) private var dismiss
var body: some View {
VStack(spacing: 24) {
Image(systemName: "sparkles")
.font(.system(size: 60))
.foregroundStyle(.tint)
VStack(spacing: 8) {
Text("Pro").font(.largeTitle.bold())
Text("Unlock everything")
.font(.headline)
.foregroundStyle(.secondary)
}
VStack(alignment: .leading, spacing: 12) {
FeatureRow(icon: "checkmark", text: "Unlimited notes")
FeatureRow(icon: "checkmark", text: "iCloud sync")
FeatureRow(icon: "checkmark", text: "Custom themes")
FeatureRow(icon: "checkmark", text: "Priority support")
}
.padding()
.background(.regularMaterial, in: .rect(cornerRadius: 12))
Spacer()
VStack(spacing: 8) {
Text("Try free for 7 days")
.font(.caption)
.foregroundStyle(.secondary)
Button {
Task { await store.purchase(annualPackage) }
} label: {
VStack(spacing: 4) {
Text("Start Free Trial")
.font(.headline)
Text("then 39.99 USD per year")
.font(.caption)
}
.frame(maxWidth: .infinity)
.padding(.vertical, 14)
}
.buttonStyle(.borderedProminent)
.controlSize(.large)
}
Button("Restore Purchases") {
Task { await store.restore() }
}
.font(.caption)
.foregroundStyle(.secondary)
}
.padding()
.overlay(alignment: .topTrailing) {
Button { dismiss() } label: {
Image(systemName: "xmark.circle.fill")
.font(.title2)
.foregroundStyle(.tertiary)
}
.padding()
}
}
}What makes this pattern work: clear value list, single decisive CTA, explicit trial language, visible restore button, and an unambiguous close button. Apple App Review approves this archetype consistently when those five elements are present.
Archetype 2: Tiered Comparison Paywall
Two plans side by side, monthly and annual, with a "Save 50 percent" badge on the annual to anchor toward the higher value option. Used by Notion, Bear, Castro, and most subscription apps once they have traction.
enum BillingCycle: String, CaseIterable {
case monthly, annual
}
struct TieredPaywall: View {
@State private var selected: BillingCycle = .annual
var body: some View {
VStack(spacing: 24) {
VStack(spacing: 8) {
Text("Upgrade to Pro")
.font(.largeTitle.bold())
Text("Unlock unlimited features")
.foregroundStyle(.secondary)
}
HStack(spacing: 12) {
ForEach(BillingCycle.allCases, id: \.self) { cycle in
PlanCard(
cycle: cycle,
isSelected: cycle == selected,
onTap: { selected = cycle }
)
}
}
FeatureList()
Button("Continue") {
Task { await purchase(selected) }
}
.buttonStyle(.borderedProminent)
.controlSize(.large)
.frame(maxWidth: .infinity)
Button("Restore Purchases") { Task { await restore() } }
.font(.caption)
.foregroundStyle(.secondary)
}
.padding()
}
}
struct PlanCard: View {
let cycle: BillingCycle
let isSelected: Bool
let onTap: () -> Void
var body: some View {
VStack(spacing: 8) {
if cycle == .annual {
Text("BEST VALUE")
.font(.caption2.bold())
.foregroundStyle(.white)
.padding(.vertical, 2)
.padding(.horizontal, 8)
.background(.green, in: .capsule)
}
Text(cycle == .monthly ? "Monthly" : "Annual")
.font(.headline)
Text(cycle == .monthly ? "9.99" : "39.99")
.font(.title.bold())
Text(cycle == .monthly ? "USD per month" : "USD per year")
.font(.caption)
.foregroundStyle(.secondary)
if cycle == .annual {
Text("Save 67 percent")
.font(.caption2.bold())
.foregroundStyle(.green)
}
}
.frame(maxWidth: .infinity)
.padding()
.background(
RoundedRectangle(cornerRadius: 16)
.fill(isSelected ? Color.accentColor.opacity(0.15) : Color.gray.opacity(0.08))
.overlay {
RoundedRectangle(cornerRadius: 16)
.stroke(isSelected ? Color.accentColor : Color.clear, lineWidth: 2)
}
)
.onTapGesture(perform: onTap)
}
}Default the annual plan selected. Three measured wins from the indie iOS A/B testing community: 30 to 60 percent more annual subscriptions vs monthly default, 8 percent overall trial start rate lift, and significantly higher LTV per subscriber thanks to lower annual churn.
Archetype 3: Hard Paywall on First Launch
The app is gated entirely behind a paywall on first launch. Used by Calm, Headspace, Tot, and many high conviction premium content apps. Effective when your value proposition is obvious and the App Store screenshots have already done the selling.
struct HardPaywall: View {
var body: some View {
ZStack {
// Background that previews the experience
Image("paywall_hero")
.resizable()
.scaledToFill()
.ignoresSafeArea()
LinearGradient(
colors: [.clear, .black.opacity(0.85)],
startPoint: .top,
endPoint: .bottom
)
.ignoresSafeArea()
VStack {
Spacer()
VStack(alignment: .leading, spacing: 16) {
Text("Master your habits")
.font(.largeTitle.bold())
.foregroundStyle(.white)
Text("Join 1.2 million people building lasting habits")
.foregroundStyle(.white.opacity(0.85))
HStack {
Text("⭐⭐⭐⭐⭐")
Text("4.9 from 50,000 reviews")
.foregroundStyle(.white.opacity(0.8))
.font(.caption)
}
Button {
Task { await purchase() }
} label: {
Text("Start 7 day free trial")
.font(.headline)
.frame(maxWidth: .infinity)
.padding(.vertical, 14)
}
.buttonStyle(.borderedProminent)
Text("Then 49.99 USD per year. Cancel anytime.")
.font(.caption2)
.foregroundStyle(.white.opacity(0.6))
HStack {
Button("Terms of Service") { showTerms() }
Spacer()
Button("Privacy Policy") { showPrivacy() }
Spacer()
Button("Restore") { Task { await restore() } }
}
.font(.caption2)
.foregroundStyle(.white.opacity(0.6))
}
.padding()
}
}
}
}Hard paywalls require strong upstream marketing. The App Store page must already convince. The paywall reinforces with social proof (review count, star rating) and removes friction (one tap to free trial). Apple App Review accepts hard paywalls when the trial terms are explicit and Restore plus Terms plus Privacy links are visible.
Archetype 4: Soft Paywall Feature Gate
The app is fully usable with a free tier. Premium features are gated and trigger a paywall on first attempt. Used by Bear, Day One, Drafts, and most productivity tools. Lower trial start rate but stronger retention because users have already invested in the app.
struct CreateDocumentView: View {
@Environment(SubscriptionStore.self) private var store
@State private var showPaywall = false
let documentCount: Int
let documentLimit = 3
var canCreate: Bool {
store.isPro || documentCount < documentLimit
}
var body: some View {
Button {
if canCreate {
createDocument()
} else {
showPaywall = true
}
} label: {
Label("New Document", systemImage: "plus.circle.fill")
}
.sheet(isPresented: $showPaywall) {
FeatureGatePaywall(reason: .documentLimit)
}
}
}
struct FeatureGatePaywall: View {
let reason: PaywallReason
var body: some View {
VStack(spacing: 24) {
Image(systemName: "doc.fill")
.font(.system(size: 60))
.foregroundStyle(.tint)
Text("You have hit the limit")
.font(.title2.bold())
Text("Free accounts can have 3 documents. Upgrade to Pro for unlimited.")
.multilineTextAlignment(.center)
.foregroundStyle(.secondary)
// Plans here
// ...
}
.padding()
}
}The reason argument lets you customize the headline based on which feature triggered the paywall. Users who hit a feature gate convert at significantly higher rates than users browsing settings, because they have a specific use case in mind.
Archetype 5: Free Trial First
The trial starts automatically on app launch (no purchase required) and the paywall appears at trial end. Used by Calm and the Calm style meditation apps. Strong retention because the user experiences the full value during the trial.
struct AppRoot: View {
@AppStorage("trialStartDate") var trialStartDate: Date?
@AppStorage("trialDays") var trialDays: Int = 7
@Environment(SubscriptionStore.self) private var store
var trialIsActive: Bool {
guard let start = trialStartDate else { return false }
return Date().timeIntervalSince(start) < TimeInterval(trialDays * 86400)
}
var body: some View {
Group {
if store.isPro || trialIsActive {
MainAppView()
} else {
TrialEndedPaywall()
}
}
.task {
if trialStartDate == nil {
trialStartDate = Date()
}
}
}
}A few things to handle correctly. One, persist the trial start date across reinstalls if your goal is preventing re trial abuse (use iCloud Key Value Store). Two, show the trial countdown in settings or a banner so users know when it ends. Three, send a push notification 24 hours before trial end (lift conversion 10 to 20 percent).
Conversion Psychology in 2026
Five patterns with measurable lift across indie iOS apps:
- Annual plan default selected. Lifts annual share by 30 to 60 percent vs monthly default. Annual subscribers churn 70 percent less than monthly.
- Most Popular or Best Value badges. Lift conversion 5 to 15 percent on the recommended plan. Pair with a discount or trial.
- 3 to 7 day free trial with no payment language. Lift trial start rate 20 to 40 percent over no trial. Be explicit: "Free for 7 days. No payment needed today."
- Inline social proof. "4.8 stars, 50,000 happy users" near the CTA. Use real numbers from your App Store metadata.
- Single primary CTA. One big button outperforms two side by side options most of the time. Reduce decision fatigue.
Test in your category. The pattern that wins for a meditation app may lose for a fitness tracker. Use RevenueCat Offerings or Superwall to A/B test without ship cycles.
App Review Rejection Patterns
The six most common reasons paywalls get rejected:
- Missing or unclear Restore Purchases button. Visible on every paywall, ideally as a tertiary button under the primary CTA.
- Free trial terms not explicit. Must say "Free for X days, then Y USD per period."
- Auto renewable subscription terms not visible. Must show price, period, link to terms and privacy.
- Requesting payment outside StoreKit. Only allowed via External Purchase Link entitlement (EU) or alternative payment options on macOS. Default iOS apps must use StoreKit.
- Pro features not delivered post purchase. Implement entitlement checks correctly. Apple verifies post purchase that the advertised features unlock.
- Dark patterns. Hiding the close button, requiring a countdown to dismiss, or making the close button intentionally hard to tap.
Fix all six before submission. Use the App Review checklist in your release process.
Paywall Placement
Three valid placements. Pick based on your category and user value perception:
| Placement | Trial start rate | Best for |
|---|---|---|
| End of onboarding (3 to 5 value screens, then trial) | 8 to 25 percent | Hard paywall apps |
| After clear value moment (saved 5 notes, scanned 3 docs) | 5 to 15 percent | Soft paywall apps |
| First attempt at premium feature | 10 to 30 percent | Feature gated apps |
| First launch, no value shown | 2 to 5 percent | Avoid (also App Review risk) |
The Calm and Headspace pattern of value first, paywall second produces 2 to 3 times higher trial start rates than first launch with no preview. Build trust before asking for the trial.
A/B Testing Without App Updates
Three approaches:
- RevenueCat Offerings. Configure multiple paywall variants in the dashboard. The SDK serves a random variant. Read the variant ID and render the matching SwiftUI view. The simplest path; works with any paywall design.
- Superwall. Paywalls are server side templates. The entire UI is hot swappable. Costs 90 to 200 dollars per month minimum but ships the most flexible no code editor on the market.
- Custom server driven UI. Your backend returns a JSON paywall description. Your SwiftUI paywall view interprets the JSON. Most flexible but requires building and maintaining the rendering layer.
Most indie apps start with RevenueCat Offerings, graduate to Superwall when paywall experimentation becomes the primary growth lever.
Real World Examples (What Top Apps Ship)
- Calm: Hard paywall after onboarding video. Annual default. Social proof ("Featured in NYT").
- Bear: Soft paywall feature gate. Free tier usable, sync and themes locked. Annual default with monthly visible.
- Headspace: Free trial first. Trial starts on launch, paywall at day 7 and again at day 14.
- Tot: Single product paywall on first launch. One price, no trial. Simple and effective.
- Things: No subscription. One time purchase only. Outlier in the category but maintains a loyal base.
- NetNewsWire: No paywall. Free open source. Reference for what users compare your paywall against.
The Swift Kit Ships All Five Archetypes
The Swift Kit ships every paywall archetype above as a reusable SwiftUI component. Single product paywall, tiered comparison, hard paywall, soft paywall feature gate, and free trial first. Each one is wired to RevenueCat and the design system tokens. Pick your archetype, edit the copy, ship.
Frequently Asked Questions
Should I build a custom paywall or use RevenueCat Paywalls v2?
Build custom if your paywall is core to your brand or you have multi step flows. Use RevenueCat Paywalls v2 if you want fast A/B testing and the templates fit. Many apps run a custom paywall plus Superwall for experimentation in parallel.
What is the average paywall conversion rate for indie iOS apps?
Rough benchmarks. Trial start rate (visit to trial start): 5 to 25 percent depending on archetype. Trial to paid conversion: 30 to 60 percent depending on category. Visit to paid (skipping trial): 2 to 8 percent. The single biggest variable is paywall placement and the value the user has experienced before seeing it.
Do I need a paywall video?
Helpful for hard paywalls in lifestyle and content categories. Less impactful for utility and productivity apps where the value is obvious from screenshots. Test before investing in video production. A 15 to 30 second loop in the App Store preview often outperforms a paywall video.
Where to Go Next
- RevenueCat in SwiftUI 2026 for the SDK that powers most of these paywalls.
- RevenueCat vs Superwall for the A/B testing tool comparison.
- StoreKit 2 in SwiftUI for the underlying purchase API.