We’re in the middle of an AI-fueled hype cycle where it feels like everyone is building apps in a weekend and making $100K a month. It is as exciting as it is misleading.
“Your app, OnTimer – Never Be Late, is ready for distribution.”
When I finally saw that message from Apple’s review team, I knew two things were true:
- Yes, you can build your own mobile app with AI
- You’re probably not going to do it in a weekend (it took me four months)
I like to joke that any idiot can build an app now — just ask me how I know. But we really are living in an amazing moment. Great ideas have never been limited to a specific set of people; anyone of any background, education, or technical ability can have a million-dollar idea. The limit has always been whether those same people have the technological know-how to turn that idea into reality. Now, as we’ve all seen, AI has erased that limitation.
The reality behind vibe coding your first app
I don’t know how to code.
When I started building the app in November 2025, I was just trying to see what was possible with vibe coding. But each time I got something to work, or fought through a bug, I got more determined to see it through.
Seeing the app in the App Store and getting my first customers has been incredibly rewarding. It was also harder than I expected.
So yes, you can vibe code a real subscription app. Is it as easy as everyone says? That’s a more nuanced answer. But I’m going to share what I learned so you can do it too, and maybe even avoid some of my mistakes.
Lesson 1: don’t wait for the perfect idea, build something
If you’ve ever gotten a frustrated text from a colleague saying, “We’re all on the Zoom, are you joining?” then you’ll understand OnTimer’s origin story.
Every morning, I used to check my calendar and set alarms two minutes before my meetings. I hate being late, and regular calendar notifications are too easy to ignore. I needed something more persistent, otherwise I’d just keep writing that email or staring at a chart.
So when I wanted to see what was possible with vibe coding, I didn’t go looking for the perfect idea, I just automated my own behavior.
I didn’t know if it could make money, I didn’t know how many other people shared the problem. I just knew I didn’t want to wait.
In a world where you can build anything, paralyzing yourself in search of that perfect, differentiated idea, is a great way to get stuck doing nothing.
So when I saw a LinkedIn post for Supervibes, ‘The vibe coder for native apps’, I got to work.
Lesson 2: pictures are not products, and AI often doesn’t know the difference
I was blown away when my initial prompts transformed my vision for OnTimer onto the screen in minutes. It’s almost intoxicating to see your app come to life like that.
But I quickly learned that there is a big difference between what you’re seeing and what is actually working. This has been a recurring theme throughout the process.
I knew oAuth would need real setup, that was expected. What I didn’t expect was that the AI would fake things that actually mattered to the user experience.
When Supervibes initially coded the app with fake calendar data, that seemed acceptable as a starting point. But it also ‘faked’ things that would come back to bite me. On the homescreen it had created a sync icon with text that said, “Auto-syncs every 15 minutes”. As it turned out, this wasn’t a feature or setting — it was pure window-dressing, but I didn’t know to question it.
It took me about a week to get oAuth and the initial calendar connections working. When my Xcode-connected test phone fired its first OnTimer alarm for a meeting, it was the first time I started to believe this could work.
But remember earlier how I told you I was an idiot? This is where that comes back into focus.
With the core functionality ‘working’, I spent my nights and weekends slogging through the App Store’s somewhat-convoluted process and finally sent a first build to TestFlight.
That was eye-opening, and not in a good way. The full screen alarms that worked so well on my test phone, when the app was in the foreground, didn’t work at all when the app was in the background. And since the automatic sync was fake, OnTimer’s never be late promise was pretty empty.
I eventually switched from Supervibes to Claude Code, but this is a ‘gotcha’ across AI tools. The ‘pictures’ they paint feel real, but pictures aren’t products. The inconsistency between what was hard-coded in, and what wasn’t, made it near-impossible to differentiate between whether something was built and functional, or just a convincing visual.
If I could go back, I would have spent a few hours with a whiteboard before writing my first prompt and asked:
- What does success look like at each stage?
- What qualifies as working?
- What are my expectations as a user?
Lesson 3: your simple app might actually be more complex than you think
Sharing that first version on TestFlight early turned out to be a great decision. The feedback was swift and painful.
Connecting oAuth turned out to be the easy part. Building a persistent notification system that works in the background is not. Making the never be late guarantee work when a phone is silenced is not. Syncing multiple calendars reliably is not. Every time I solved one challenge, a new one seemed to appear.

This is somewhat the nature of AI: what you see from the outside appears functional and sleek. Even when a problem arises, it seems to be resolved fairly simply. But behind each challenge and subsequent resolution, the respective jerry-rigged solutions become knots that come back around to haunt you. Because we only see the front of the AI tool, it often appears problems are solved, when actually they’ve just been plastered over.
I learned quickly that there is a lot of complexity in building a ‘simple’ app. As a vibe coder, this is where you are kind of on your own.
On a team, you have people and experience to think this stuff through. Often you avoid pitfalls because your engineers have already run into them before. With vibe coding it’s just you and an LLM. If you don’t ask the right questions, it’s hard to know what’s coming next.
Here’s what I should have done differently:
- Asked an LLM to compare my plan to app store rules and iOS limitations
- Created a ‘Perfect.md’ file that described the ideal end-to-end user experience and forced Claude to align every change to it
- Talked through my idea with others (humans!) to uncover challenges early
Lesson 4: the vibe coding landmines are scary, but they aren’t deadly
Three or four times as I was building OnTimer, I hit walls that seemed insurmountable. I ran into issues that brought everything to a halt, and pushed me to the edge of my sanity.
A few weeks in I got caught in a cycle. Identify bug → prompt Claude to fix → Claude says “Perfect, I fixed it” → nothing changes → repeat
My prompts eventually devolved into me telling Claude to “Go F%ck itself” which didn’t help.
In a moment of desperation, I asked Claude to show me how to manually make a change to one word on my homescreen. I was losing my mind, and Claude couldn’t even make the simplest of changes, let alone fix the bug.
Then I saw my manual change instantly revert itself. I didn’t know why, but I finally saw what was happening. It turned out an update I made was causing new code to save to a backup drive, while the live file stayed static.
It was a week of hell, for what turned out to be a five-minute fix.
The problem with vibe coding is that you don’t have the same instincts or approach engineers have. We can’t look at the code the way they can. When things break, it’s easy to get lost.
But here is what I learned: don’t keep doing the same things over and over that aren’t working, and don’t let Claude (or *insert AI tool*) do it either. Even when you try to prompt root cause analysis, it can have a tendency to just keep trying to fix the same area of your code. You have to get it out of its own way.
A good tactic I have found is to use another LLM to challenge Claude. If a fix doesn’t work I bring in ChatGPT:
- I share the Claude Code thread and relevant files, and ask ChatGPT for a fresh analysis and prompt
- I send the prompt to Claude in Plan mode, and go back and forth between the two LLMs
- When it’s fixed, I update my Claude.MD file with a detailed explanation to prevent similar issues in the future
Bugs are probably the worst part of vibe coding. They’re not just time-killers; they rob you of your confidence. It’s not fun, but the more you battle through these, the faster and better you get at it.
Lesson 5: monetize early, you won’t regret it
From the beginning I knew I was going to launch OnTimer as a subscription app. Monetizing your app forces you to focus on value delivery and product-market fit. Those are great forcing functions, even when you are still learning.
You will have to make real decisions: freemium vs. paid, free trial lengths, what lives behind the paywall and what doesn’t. I chose freemium with an annual subscription. The free tier lets users experience the core alarm functionality. The paid tier unlocks multiple calendars and Time-to-Leave departure alerts.

Figuring out what to place behind the paywall forced me to ask myself what was valuable enough to pay for, and what needed to be free to get someone hooked. That thinking made OnTimer a better app.
Monetization adds layers:
- App Store complexity: subscription apps get more scrutiny from reviewers, and rejections are more painful when you’re trying to ship
- Entitlement logic: your app needs to know what a user has paid for, and show it appropriately
- Paywall considerations: a bad paywall doesn’t just hurt conversion, it can get your app rejected entirely
Fortunately, RevenueCat makes this a lot faster and easier. They provide an integration prompt for vibe coders, which was like magic.

I fed it into Claude and within minutes I was walking through RevenueCat’s setup guide. In less than a day I had a working paywall.
It wasn’t perfect. I did get rejected from the App Store twice because of a paywall issue — a nuance in the RevenueCat UI builder looked correct visually but wasn’t behaving right in practice, reverting to a default state rather than the one I’d selected. I hit customer support, quickly got it sorted, and finally got OnTimer approved.
What was cool though, is that I went back into the paywall builder a few days ago, and the issue I ran into had been fixed. It’s great when your feedback helps the next developer avoid the same pitfall.
RevenueCat did the heavy lifting so that I could focus on developing the app’s core value. They handle the logistics of your subscription infrastructure so you can stay focused on building something people want to pay for.
So, I really encourage you to monetize early because:
- It forces honest conversations about value: if someone won’t pay for it, that’s information — find out early
- Subscribers give better feedback than free users: they have skin in the game and they want it to work
- Revenue changes your psychology: even a few dollars a month makes you more serious about shipping and improving
Go build your first app, it’s worth it
You should absolutely go build your first app. It’s not as easy as the hype makes it sound. Things break, and you hit walls. You have moments of real frustration and doubt.
But you also have moments of amazing accomplishment. Yesterday I had a doctor’s appointment, and OnTimer’s Time-to-Leave feature fired off an alarm based on traffic and distance.
I built that!
…Okay, Claude helped.
The point is that vibe coding is real. You may not make $100K/month right off the bat like many on LinkedIn and X would have you believe — it will probably take longer than you expect. It took me about four months to launch. But if you push through the hard parts, you can build something you are proud of.
Now I’m shipping, learning, and even starting to see the first signs of revenue. The next challenge is growing it, and that’s going to be hard too.
But I’m in it now, and you can bet this won’t be the only app I build.
AI got me started. Persistence is what got me here.
Check out OnTimer – Never be late on the App Store!

