Starter kits in four stacks

The templates I start every app from, and why each one ships with the boring parts already done.

Period
2025 – 2026
Scope
6 templates
Stack
Flutter, SwiftUI, Kotlin Multiplatform, React Native
Status
Used for every new app

Problem

Every app I build needs the same unglamorous things before it does anything interesting: onboarding, a paywall, settings, theming, dark mode, notifications, app icons and a release pipeline. Rebuilding those each time was slow, and worse, it was where bugs hid.

Approach

I keep a starter for each stack I use, and every one follows the same rules.

Re-skin from one file. Colours, type, spacing, radii and even the depth of a button press live in a single theme file. A new app starts by changing tokens, not by hunting through screens. Each starter also ships with a component gallery, so a theme change can be checked in one place.

Purchases behind a seam. The UI never talks to a purchase SDK directly. It talks to a small interface, and the starter ships with an offline mock behind it:

protocol PurchaseProviding {
    func currentOffering() async throws -> SubscriptionOffering
    func purchase(_ package: SubscriptionPackage) async throws -> Bool
    func restorePurchases() async throws -> Bool
    func isSubscribed() async -> Bool
}

That means the paywall can be designed, previewed and tested on day one, with no store account, no API keys and no sandbox users. The real provider is dropped in at the end.

Release automation included. Fastlane lanes for test, beta and release, plus CI that runs analysis and tests on every push. Shipping a TestFlight build should be one command from the first week.

Generic content only. Placeholder copy and neutral sample data, so a starter never leaks one product into the next.

The kits

  • Flutter. My main starter, refined since April 2025. MVVM with repositories, dependency injection, localisation, a paywall with a one-time discount downsell, one-command icons and splash screens, and a script that scaffolds a new feature folder.
  • SwiftUI. No third-party dependencies. Data-driven onboarding, real local notifications, the purchase seam above, and a bold 3D-button design system.
  • Kotlin Multiplatform. Shared ViewModels, networking and persistence, with fully native UI on each side: SwiftUI on iOS, Jetpack Compose on Android.
  • React Native (Expo). Expo Router, NativeWind and persisted state, and it runs in Expo Go with no native build.
  • Two lighter templates. A calm Material 3 Flutter shell and a SwiftData-based SwiftUI template for simpler apps.

Outcome

Every app I've started since uses one of these. The first day of a new project is now spent on the part that's actually new. Lumi, TwentyFit and FORQ were all grown from these starters.

← Work