Inspiration

I kept getting stuck on one idea: how much of who you are came down to a moment you almost didn't notice. The job you almost didn't take. The move you almost didn't make. There's this line from Heroes Hiro, the time-travel guy, freaking out about "too many butterflies" that never left my head: touch one small thing and the whole future downstream of it unravels.

I wanted to actually let people sit inside that feeling instead of just reading about it somewhere. Not a personality quiz. A real story that forks around your specific what-if and keeps forking every time you make another call.

What it does

You type one what-if "what if I'd taken the job in another city," whatever's actually been living in your head and Butterfly writes it forward into three different lives from that one fork. Each one keeps branching as you go: every chapter ends on a real choice, not just a "tap to continue."

Stories generate entirely on-device. Nothing about your what-if ever has to touch a server. Free chapters get you hooked, then you can unlock a single life on the cheap or unlock everything forever.

How we built it

Expo/React Native under the hood, with three layers doing the actual storytelling:

  • A base of hand-written, structured template content, so the app never has nothing to say.
  • On-device generation on top of that: Apple's on-device models first, a local GGUF model as backup, template as the last-resort safety net.
  • RevenueCat running the money side: a cheap one-off unlock for one life, a lifetime purchase for all of them, both wired through RevenueCat's entitlements and Paywall UI instead of me hand-rolling receipt checks.

Challenges we ran into

Almost none of the real pain was in the app code. It was Apple's machinery:

  • My bundle ID turned out to already be registered under a different Apple team from old local testing bundle IDs are global across every Apple account you've ever touched, not just your current one, so I had to burn a new one and re-provision everything from scratch.
  • RevenueCat kept telling me my In-App Purchase key was invalid, no matter how many times I regenerated it. Turned out my Paid Applications Agreement hadn't actually been signed yet, which quietly blocks IAP API access and just looks like a bad key.
  • The big one: every production build failed on a provisioning-profile mismatch, even right after I'd re-enabled the exact capability it was complaining about in Apple's portal. Chased that one all the way into a dependency's Expo config plugin, it only added the entitlements the build needed based on an environment variable that got evaluated differently in two different phases of EAS's own pipeline. Found it by actually reading the plugin's source instead of guessing at Apple's dashboard for the fourth time.

Accomplishments that we're proud of

Going from "Apple Developer account still pending" to an actual submitted App Store build in under a week, with a real two-tier RevenueCat setup working end to end and generation that runs fully on-device with zero server dependency. Also proud of catching and fixing that EAS/entitlements bug for real instead of just papering over it by disabling the feature it was blocking.

What we learned

That a 2048-token context window forces real honesty about what a story needs to remember, I ended up feeding the model a short condensed summary instead of full chapter history, and it made the writing better, not just cheaper. That not every purchase should be an entitlement, separating "unlock this one thing" from "unlock everything" cleanly saved me from a mess of paywall logic later. And that most UI polish is just finding the one dumb flexDirection: "row" wrapper that's been quietly shrinking a button for months.

What's next for Project Butterfly: Life Branches

Android is the obvious next stop, the app's already built for it, it just needs its own RevenueCat setup and a real testing pass. Past that: real accounts so a life you started on your phone follows you to a new device, more categories and longer story arcs, and building out the share feature into something more social, letting people actually compare the different lives they and their friends ended up writing.

Built With

Share this project:

Updates

Submission history