



I didn't set out to learn UI/UX. I set out to build an app that tracks what you eat at buffets. But somewhere between the first TestFlight build and the fiftieth bug report, I ended up learning more about design than I ever did about Swift.
Early on, I was fixated on the obvious stuff — does the camera work, does the calorie estimate come back, does the session save. Those are easy to catch because they're loud: the app crashes, or it doesn't. The bugs that actually hurt the product were quiet. A referral link that shared but pointed to the wrong restaurant. A paywall that popped up the instant someone tapped "Eating Here!" on their second visit — before they'd taken a single photo, before they'd gotten any value at all. Nothing crashed. Nothing broke. The app just made someone feel unwelcome at exactly the wrong moment, and they closed it.
You don't find that kind of bug in a stack trace. You find it by watching someone actually use the thing, or by trying to imagine being them for a minute.
The paywall was technically doing its job — gating a feature at a limit, exactly as designed. But "correct" and "good" turned out to be different questions. The fix wasn't a bug fix in the traditional sense; it was recognizing that when something happens matters as much as whether it happens. Same feature, same limit, same eventual paywall — just moved to the end of the session, after the person had already gotten something out of using the app, with the paywall showing up as a tap-to-unlock on blurred stats instead of a wall blocking the door. Nobody would have filed that as a bug. It just quietly made people leave.
That's the shift: stop asking "does this work" and start asking "what does this feel like, three seconds before and three seconds after."
I used to think some people are just "detail-oriented" and some aren't. What actually happened is I got burned enough times — an App Store rejection over iPad orientation support I didn't know was required, a version number bump that didn't take because I archived before the fix landed — that I started reflexively checking the boring stuff before shipping. Not because I'm naturally careful, but because carelessness had a cost I could point to. The muscle builds from friction you personally felt, not from reading a best-practices list.
At some point I realized I was trying to reverse-engineer virality from first principles, which is slow and mostly wrong. So I stopped guessing and started reading — growth blogs, teardown threads, the odd research paper on habit loops and referral mechanics, and posts from people who'd actually built something that spread. One that stuck with me was from the developer behind GlowUp, which went genuinely viral — reading how they thought about the product loop reframed a lot of my assumptions. The takeaway wasn't a tactic to copy, it was a mindset: growth isn't a feature you bolt on at the end, it's a property of the core loop itself. If the moment right after someone gets value isn't also the moment they're nudged to share it, invite a friend, or come back tomorrow, you're leaving growth on the table no amount of marketing will make up for.
That's part of why the referral link bug mattered more than it looked like on paper — a share flow that points to the wrong restaurant isn't just a broken link, it's a broken growth loop. Same with the paywall timing: gating too early doesn't just cost a subscriber, it costs the share, the review, the return visit that would've come after a good first experience. Once I started reading growth-focused writing alongside doing my own UX pass, I stopped treating "does this convert" and "does this feel good to use" as separate problems. They're the same problem, just measured differently.
Most of what people call "good taste" in product design is just paying attention long enough to notice the fifty tiny moments where the software could be kinder to whoever's using it — and then actually going back and fixing them, even when nothing's technically broken.