Entry #12
2026-08-03
5 min read
Monetizing with RevenueCat: Building the founder promise into Ritual
Planning ahead
I haven't hit 1,000 users yet. But I'm already thinking about what happens when I do.
When I launched Ritual, I made a promise to myself: if you're here before monetization, you're a Founder. You get all the features free forever. Not because I'm nice, but because you believed in Ritual when it was fragile.
The challenge is: how do I actually build that promise into the app in a way that scales?
That's where RevenueCat comes in.
The story behind Ritual
I launched Ritual as a free app. You were here when it was just an idea. You helped Ritual figure out if this space for release and gratitude was something the world actually needed.
Ritual is about emotional architecture, balance. Release the heavy moments. Capture the joyful ones. So when I eventually add subscriptions, it needs to feel right. It can't feel like I'm punishing the people who got here first.
I made myself a promise: if you're here before I hit 1,000 users, you're a Founder. When monetization happens, you get all the premium features forever, free.
The question isn't whether to keep that promise. It's how to build it into the app from the start so that when the time comes, it just works. That's why I chose RevenueCat.
How I'm building it
When I set up RevenueCat integration, I created two simple switches in the system that will track user status:
var isLegacyUser: Bool // "Were you here before monetization?"
var isPro: Bool // "Are you paying us right now?"
Think of it like this:
- Legacy User = You got here before the paywall existed
- Pro = You're currently paying (subscription or lifetime)
When monetization launches, I'll flip the legacy switch for everyone who's here before that moment:
func claimFounderStatus() {
self.isPro = true // ✓ You're a pro user
self.isLegacyUser = true // ✓ You're legacy too
// Save this to the cloud so it works on all your devices
iCloudStore.set(true, forKey: Keys.isPro)
iCloudStore.set(true, forKey: Keys.isLegacyUser)
}
Then the access logic is simple:
var hasProAccess: Bool {
isLegacyUser || isPro // "If you're EITHER legacy OR paying, you get access"
}
This means:
- Legacy users (you from day one) = Free forever
- Pro users (people who pay) = Access while they pay
- New free users = See the paywall and limited features
Behind the scenes
When you open Ritual, the app checks one thing:
if hasProAccess {
showAllFeatures() // ✓ See everything
} else {
showLimitedFeatures() // Only 3 free entries
}
When you sign in on a new device, your legacy status travels with you via iCloud:
var selectedThemeID: String {
get {
return _localThemeID ?? iCloudStore.string(forKey: Keys.selectedThemeID) ?? "classic"
}
set {
// Save to iCloud so ALL your devices know about it
if let sharedDefaults = UserDefaults(suiteName: "group.com.maxiruti.Sigh") {
sharedDefaults.set(newValue, forKey: "selectedThemeID")
}
}
}
You get a new phone? It knows you're legacy. You sign in on your iPad? It knows.
Why RevenueCat
Before RevenueCat, I would only have App Store numbers. Those numbers don't tell me who actually loves Ritual or who's been here from the beginning.
RevenueCat lets me track user history and status, which is critical for keeping my promise to founders. When someone joins now and then monetization launches later, I need a system that remembers them.
That's what RevenueCat does. It tracks:
if productID.contains("lifetime") {
self.isLegacyUser = true // Lifetime buyers get legacy status
self.isPro = true
} else {
self.isPro = true // Regular subscribers just get Pro
}
I also tag them in RevenueCat so I can keep track of who's been there since the beginning:
Purchases.shared.attribution.setAttributes([
"isLegacyUser": "true",
"grantedAt": "\(Date().timeIntervalSince1970)"
])
This way, when I look at RevenueCat's dashboard, I know exactly who my founders are and can treat them right.
The three types of users
┌─────────────────────────────────────────────────────┐
│ YOU ARE HERE (FOUNDER) │
│ │
│ isLegacyUser: true ✓ │
│ isPro: true ✓ │
│ hasProAccess: YES ✓ (free forever!) │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ SOMEONE WHO PAYS FOR RITUAL │
│ │
│ isLegacyUser: false ✗ │
│ isPro: true ✓ (active subscription) │
│ hasProAccess: YES ✓ (while they pay) │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ SOMEONE BRAND NEW TO RITUAL │
│ │
│ isLegacyUser: false ✗ │
│ isPro: false ✗ │
│ hasProAccess: NO ✗ (sees limited features) │
└─────────────────────────────────────────────────────┘
The real point
I haven't monetized yet. But when I do, I want it to feel right.
RevenueCat gives me the infrastructure to honor the people who believed in Ritual before it was profitable. The founder promise isn't just words—it's built into the code, tracked in RevenueCat, and ready to go live the moment I flip the switch.
That's what good monetization looks like. Not a surprise. Not a betrayal of trust. Just a simple system that says: "You believed in us. We remember."
Questions?
Q: Will this ever change?
A: Nope. Founder status is permanent. It's my way of honoring the people who believed in Ritual before I knew if it would work.
Q: What if I delete the app and reinstall it?
A: Your status is saved in iCloud, so it comes back when you sign in.
Q: What if I want to support Ritual anyway?
A: You're already getting everything. But if you want to support the work, you can upgrade to a lifetime pass. I'll love you extra.
Q: Why both isLegacyUser and isPro?
A: Because some people might be both. You're legacy and free forever, but you bought the lifetime pass to support Ritual. I wanted to track both stories.