Skip to content
Brandon Ta logo Brandon Ta
vi
All Projects Building

StreakFire — Week 1–4

Building a habit-streak iOS app in public: 4 weeks from idea to TestFlight, CloudKit sync, and first 12 users.

Swift SwiftUI CloudKit WidgetKit

Context

Context

Habit tracking is one of the most crowded categories on the App Store. So why build another one?

I kept running into the same problem with every habit app I tried: a single missed day would collapse my streak and with it, all motivation to continue. The apps were optimising for the wrong thing — they rewarded perfection, not persistence.

StreakFire’s core thesis is different. A streak should survive one human mistake. The “fire” metaphor earns its name: a fire can survive a brief gap in fuel before it goes out. That single design decision — a grace day that doesn’t reset you to zero — changes the entire emotional contract between the user and the app.

I also wanted to build this completely in the open. No stealth mode, no private beta hidden behind a waitlist. Every architectural decision, every TestFlight build, every retention number goes public as it happens. That accountability is the point.

Build log

The four-week timeline above covers the key milestones. What the timeline doesn’t show is the dead ends: a Core Data migration that I scrapped in favour of CloudKit on day 3, a widget design that looked great in Figma and terrible on an actual Lock Screen, and a notification permission flow that I rewrote twice before it felt respectful rather than aggressive.

The real build log lives in the weekly diary entries. This section is the summary — the decisions that stuck.

Tech choices & trade-offs

SwiftUI over UIKit. SwiftUI’s declarative model maps cleanly to a habit tracker’s state: you describe what the UI looks like for any given streak count, and SwiftUI handles the transitions. The trade-off is predictability — SwiftUI animations occasionally surprise you in ways UIKit never would. Accepted that cost for the faster iteration speed.

CloudKit private database over a custom backend. No server to maintain, no auth to build, and Apple handles the sync conflict resolution. The downside: no server-side analytics, no ability to run queries across users. For a solo-built v1, that’s the right trade-off. I can layer a lightweight backend later if the user base justifies it.

WidgetKit from day one. Adding widget support after the fact is painful — the data model needs to be designed with WidgetKit’s stateless timeline in mind from the start. Doing it in week 2, before the data model was locked, saved me a significant rewrite.

No third-party analytics SDK. Privacy is a genuine constraint in the App Store habit-tracker category — users are suspicious of what you’re tracking. I built a minimal event logger that writes anonymised JSON to CloudKit. I get retention curves and funnel data; users get zero data leaving Apple’s infrastructure.

What I’d change: I underestimated the complexity of WidgetKit’s timeline scheduling on older OS versions. iOS 16 and 17 handle widget refresh budgets differently. I burned a day on that. Next time I’d write the WidgetKit layer first as a standalone test harness before integrating it with the main app.

Metrics — 30 days

12 TestFlight users as of week 4. That’s a small number, and I’m not pretending otherwise. These are all people I know or who responded to my build-in-public posts — not cold discovery. What the number does tell me is that the core loop works: people are opening the app daily and logging habits without prompting from me.

  • Crash-free rate: 99.8% across 847 sessions (TestFlight Organizer)
  • Day-3 retention: 58% for the week-4 cohort (4 out of 7 week-4 testers returned on day 3)
  • Average daily check-ins per active user: 1.4 habits tracked per day
  • Most common session length: under 30 seconds — exactly what a check-in app should be

The retention number is encouraging for a v1 with no retention mechanism beyond push notifications. I haven’t optimised notifications yet — that’s the week-5 focus.

Retrospective

Four weeks in, StreakFire is a real app used by real people. That’s the only milestone that matters at this stage.

The things that went well: the CloudKit decision, the early WidgetKit investment, and the decision to ship to TestFlight in week 3 rather than polishing for another two weeks. The feedback from those first 4 testers reshaped the onboarding flow in ways I couldn’t have anticipated from solo testing.

The things that didn’t: I spent too long on the visual design of the streak flame before I had any user validation that the metaphor resonated. That’s a classic founder mistake — falling in love with the brand before proving the core mechanic. The mechanic works; the flame visual is still being iterated.

What’s next: week 5 brings notification personalisation (let users set their own reminder windows), a share card for posting streaks to social, and the first attempt at App Store Connect submission. The goal is a public App Store listing before the end of April.

I’m building this to ship, not to prototype. The public record is the accountability mechanism.

Build Log

  1. Week 1

    Research & scoping

    Mapped the existing habit-tracker landscape. Identified the gap: most apps optimise for streaks as vanity metrics rather than recovery. Scoped StreakFire to two primitives — a daily check-in and a 'fire' visual that survives one missed day.

  2. Week 2

    Core data model + Widget PoC

    Settled on CloudKit private database for zero-friction sync across devices. Built the HabitRecord struct and first WidgetKit timeline entry. Confirmed the widget refreshes correctly in the iOS simulator without entitlement errors.

  3. Week 3

    Streak math + first TestFlight

    Implemented the streak calculation engine including the grace-day logic. Wrote 14 unit tests covering edge cases (timezone crossings, DST shifts). Submitted build 1 to TestFlight; onboarded 4 testers from my network.

  4. Week 4

    Onboarding + retention instrumentation

    Added a 3-screen onboarding flow with permission prompts for notifications. Integrated anonymous analytics via a lightweight event logger (no third-party SDK — privacy first). Day-3 retention for week-4 cohort: 58%.

Tech Choices & Trade-offs

Metrics — 30 days

30-day snapshot

12

Active Users

TestFlight seed users, week 4

Retrospective