Share

19 Days, 239 Commits, and One Lesson in Restraint

April 05, 2026 • tech

19 Days, 239 Commits, and One Lesson in Restraint
mobilereact-nativeexpoai-assisted-developmentleaderboard-fantasycomposerindie-saas

19 Days, 239 Commits, and One Lesson in Restraint

The last mobile app I built professionally was a material showcase app for Bradley Corporation. Objective-C. Xcode. Manually managing memory with retain and release. If you wanted to support Android too, you wrote the whole thing again in Java. That was roughly 2013.

I haven't touched mobile development since.

Once I finally decided to add a native mobile app for Leaderboard Fantasy, I knew I was walking into a world I hadn't seen in over a decade. What I didn't expect was just how different that world would look — and how fast I'd be able to move through it.

Why Mobile, Why Now

Leaderboard Fantasy has been growing. Slowly. A user or two every week — enough to keep me motivated, not enough to validate that the idea has real longevity. I've been watching the analytics, and the pattern is clear: people discover the platform, try it on their phone's browser, and the experience is... fine. But "fine" doesn't drive retention.

I'd also hit a natural lull. No urgent bugs. No feature requests piling up. The SaaS platforms are stable. It was the perfect window to take a swing at something bigger.

The hypothesis was simple: a native mobile app would lower the barrier to entry, improve the experience for the users I already have, and open up capabilities — push notifications, deep links, a presence in the app stores — that a responsive web app just can't match.

Mobile Is Harder Than I Remember

I sat down expecting mobile development in 2026 to be simpler than what I remembered. It's not simpler. It's different. And in some ways, it's more complicated.

Back in the Objective-C days, the decision tree was straightforward: pick a platform, learn its SDK, ship. Now you're choosing between native iOS and Android (Swift/Kotlin), Flutter (Dart), React Native (TypeScript), and half a dozen other frameworks — each with their own trade-offs around performance, ecosystem maturity, and developer experience.

I used Gemini as a research partner here. Not for code — for architecture. I spent time having real conversations about the trade-offs. What's the current state of React Native vs. Flutter? How mature is Expo's managed workflow? What does the path to the App Store actually look like for each option?

The answer I kept coming back to: React Native with Expo. Largest ecosystem. Managed workflow that handles the build infrastructure. One codebase, two platforms. TypeScript — which I have been using on TutorPro. Expo's file-based routing felt immediately familiar coming from years of Spring Boot and structured project layouts.

The Sprint — 19 Days in Three Acts

Here's where it gets wild.

On March 17th, I committed the initial Expo scaffold. By April 5th — 19 days later — the app had JWT authentication, OAuth social login (Google and Facebook), full tab navigation, contest browsing and joining, group management, a notification system with swipe gestures, push notifications, deep linking, Sentry crash reporting, Caddie AI integration, light and dark themes, Maestro E2E tests, a CI pipeline, and was ready for app store submission.

239 commits. Roughly 130 pull requests. A couple hours a day after work, plus weekends.

gantt
    title From Scaffold to App Store
    dateFormat  YYYY-MM-DD
    axisFormat  %b %d
    section Week 1
        Scaffold + Architecture     :2026-03-17, 1d
        JWT Auth + OAuth            :2026-03-20, 1d
        Tab Navigation + Screens    :2026-03-20, 2d
        Core Screens (Contests, Groups) :2026-03-20, 3d
        Privacy + Display Names     :2026-03-21, 2d
    section Week 2
        Dashboard Polish            :2026-03-23, 2d
        Notifications + Gestures    :2026-03-24, 2d
        Theme Switching             :2026-03-25, 1d
        Hamburger Menu + UX         :2026-03-25, 2d
        Maestro E2E + CI Pipeline   :2026-03-23, 1d
        Profile + Settings          :2026-03-26, 2d
    section Week 3
        Push Notifications          :2026-03-30, 2d
        Deep Linking                :2026-03-30, 2d
        Sentry + Social Login       :2026-03-30, 1d
        Caddie AI Integration       :2026-04-01, 1d
        Email Redesign              :2026-04-02, 1d
        App Store Prep              :2026-03-31, 4d

Week 1 was foundation. Scaffold the app, build the authentication layer (JWT tokens with rate limiting and token revocation — security first), wire up OAuth for Google and Facebook, and get the basic navigation structure in place. By the end of the week, you could log in, see a dashboard, and browse contests.

Week 2 was where it started to feel like a real app. Dashboard polish with featured contest carousels. Full contest and group management. A notifications tab with swipe-to-dismiss gestures. Light and dark theme support. I also set up Maestro for end-to-end testing and a CI pipeline — because shipping fast without tests is just shipping bugs fast.

Week 3 shifted to the features that make mobile mobile. Push notifications with badge counts and channels. Universal Links and App Links for deep linking into specific contests and groups from emails. Sentry for crash reporting. And then the polish — hero images on the dashboard, app icons, splash screens, and all the metadata needed for app store submission.

Leaderboard Fantasy on iPhone — the dashboard with active contests, hero banner, and tab navigation.

Leaderboard Fantasy on Android — the Masters Tournament contest detail with Augusta National in the background.

Same codebase. Two platforms. That still kind of blows my mind coming from the "write it twice" era.

The Toolchain

I should be clear about something: AI wrote nearly all of this code. Not a cloud-based coding agent with a monthly subscription — my own self-hosted setup.

If you've been following along, you might remember my posts about remote agent experiments and Composer. Composer is a dev team harness I built that runs on a dedicated Mac Mini in my house. It's evolved significantly since I first wrote about it, and this project was the proving ground.

My workflow looked like this: I'd plan features — sometimes interactively with Claude Code on my laptop, sometimes by writing up tasks for Composer to work through overnight. Gemini served as my research and architecture partner, especially early on when I was evaluating frameworks and making structural decisions. Every task, whether interactive or async, was expected to produce code, tests, and documentation. No exceptions.

The result? Composer has officially replaced my use of cloud-based coding agents. The nuance of my projects — the conventions, the design system, the API contracts — is something a self-hosted agent that lives with your code just handles better. And running my own workloads on hardware I control means no recurring subscription costs eating into the margins of a side project.

The Lesson — Restraint

Here's the thing nobody warns you about when AI can build features in minutes: the bottleneck shifts from building to validating.

AI is phenomenal at the happy path. Give it a feature spec and it'll produce working code, often on the first try. But "working" and "right" aren't the same thing. AI still tends to focus on the golden path — the scenario where the user does exactly what you expect. It doesn't notice that a button is 2 pixels off center. It doesn't catch that a swipe gesture feels sluggish on an older device. It doesn't question whether a feature should exist in the first place.

That last one is the big one.

When building is cheap, the temptation is to build everything. Every feature the web app has. Every nice-to-have that crosses your mind. Every polish item that would make the app 2% better. AI will happily oblige. It doesn't have an opinion about scope. It doesn't push back and say "hey, do we really need this for launch?"

That's your job. And it turns out it's the hardest part.

I intentionally left features out of the mobile app that exist on the web. Not because they aren't valuable — because they aren't valuable right now. The goal is MVP. Get it in the app stores. Get it in front of users. Let analytics and real feedback tell me what to build next, not my assumptions about what people want.

The human skills that matter in AI-assisted development aren't the ones you'd expect. It's not about writing better prompts or understanding model architectures. It's taste — knowing what good looks like. It's prioritization — deciding what matters this week. And it's restraint — the discipline to say "not yet" when the machine is ready to say "yes."

UI testing on real devices remains the single biggest bottleneck. It's slow, it's manual, and it's absolutely irreplaceable. A screenshot in a simulator doesn't tell you how a gesture feels. An emulator doesn't reveal that your hero image renders upside-down on a specific Android device because of EXIF orientation data. These are the things only human eyes and hands can catch — and they take time that no amount of AI acceleration can compress.

What's Next

The app is built. I'm currently waiting on Apple to convert my individual account into an Organization developer account — once that's in place, I'll submit to both the App Store and Google Play. Hopefully live by the end of the month.

The real test comes after launch. Will a native mobile app drive the user growth that Leaderboard Fantasy needs? Will push notifications keep people engaged through a tournament weekend? Will the app store presence bring in users who would never have found the web app? I don't know yet. But I'll have data soon.

What I do know is this: thirteen years ago, building a mobile app was a several months-long endeavor requiring platform-specific expertise. Today, a software architect with a self-hosted AI dev team and a few hours a day can go from zero to app-store-ready in under three weeks. AI has reinvigorated what it means to build software. The creative energy it unlocks — the ability to think of something Tuesday evening and have it working by Wednesday morning — that never gets old.

But the craft hasn't changed. Someone still needs to care about the details. Someone still needs to say "enough." The tools are wildly different. The discipline is exactly the same.

–Jeremy


Thanks for reading! I'd love to hear your thoughts.

Have questions, feedback, or just want to say hello? I always enjoy connecting with readers.

Get in Touch

Published on April 05, 2026 in tech