XenneX/LLC
All posts

The Stack Choices I Made 3 Years Ago. Do I Regret Them?

Mid-2022 was when I locked in the technical decisions that are now baked into everything XenneX ships. Some aged well. Some I live with. A couple I'd do differently if I were starting today.

#indie dev#tech stack#retrospective#react native#iOS#lessons learned
The Stack Choices I Made 3 Years Ago. Do I Regret Them?

Mid-2022 was the last time I made significant technology decisions from scratch at XenneX. Everything since then has been built on top of those choices — or constrained by them. Three years of shipping gives you a pretty honest read on what holds up.

Here's where I landed.

React Native Over SwiftUI: Slight Regret

In mid-2022, SwiftUI was in its third major iteration and still had real gaps. RN gave me cross-platform coverage — same codebase shipping iOS and Android — and the ecosystem was mature enough that I wasn't pioneering anything. It felt like the pragmatic choice.

The part I underestimated: the maintenance cost of keeping a React Native project healthy isn't zero, and it compounds. Every major RN release is a potential disruption. The third-party native module ecosystem has stabilized but it's still a layer of indirection you're managing permanently. And Apple's platform capabilities — widgets, Live Activities, Stage Manager on iPad — are always first-class in SwiftUI and second-class (or unavailable) in RN.

If I were starting fresh today, I'd lean SwiftUI for anything iOS-first. The framework has matured significantly. The performance gap that justified RN in 2022 is largely gone.

That said: if I actually need Android coverage and it's not an afterthought, RN is still defensible. The honest question is whether the Android reach was ever worth what I paid for it.

Supabase for the Backend: No Regrets

This one aged well. Supabase was earlier-stage in 2022 — betting on it felt like a calculated risk. Postgres under the hood, real-time subscriptions, auth built in, an open-source escape hatch if they went sideways. The team shipped consistently, the platform matured, and the community landed on it as the default indie backend in a way that created a real ecosystem around it.

Row-level security remains slightly underrated as a feature. Getting that right early meant I never had to retrofit auth logic into the data layer.

The only caveat: the cold-start latency on edge functions is still real. If you're doing anything latency-sensitive, you feel it.

Subscription-First Monetization: Good Call

Switching from one-time purchase pricing to subscription in 2022 felt genuinely risky. Users were complaining about subscription fatigue at the time and it was a real concern. But the App Store was clearly moving that direction, Apple's StoreKit 2 made it significantly easier to implement properly, and the unit economics for a solo developer who needs predictable revenue make subscriptions the right structure.

Three years in: it was the right call. The users who subscribe are better users — higher engagement, more invested in the product working, more likely to actually report bugs rather than leave a one-star review. Churn is a real thing you manage, but it's a better problem to have than the feast-or-famine of launch spikes with no recurring revenue.

Ignoring iPad: Actual Regret

Phone-first was the right framing for 2019. In 2022, M1 iPads existed, Stage Manager was coming, and the signals were there that Apple was serious about iPad as a productivity platform. I saw the signals and didn't act on them.

The cost has been moderate but real: iPad users who try the phone-optimized layout on a 13-inch Pro have a subpar experience, and fixing it now requires real design and engineering work rather than the incremental effort it would have been if I'd done it in 2022.

This is the one I'd go back and change if I could.

Rolling a Custom Component Library: Regret

This felt like the right call at the time — Tailwind was still controversial in 2022 and rolling your own gave you control. The problem is that utility-first CSS has clearly won, the shadcn/ui ecosystem has created a level of component quality that's hard to match with a custom library, and now I own a maintenance burden on components that aren't better than what I could get off the shelf.

I'd start with Tailwind and shadcn from day one today. The hours I spent building and maintaining the custom library would have been better spent on product.


The honest summary: two decisions I'd keep, one I'd reverse on the margin (RN → SwiftUI for iOS-first), one I'd reverse completely (iPad), one I actively regret (custom components).

Most of this is irreversible without significant rewrites. The lesson isn't that I should have been smarter in 2022 — it's that the decisions that look obvious in retrospect rarely announce themselves as obvious at the time. The best I can do is be honest about what I'd do differently, and apply that to the decisions I'm making now.