Designing and building a lightweight iOS browser with Claude Code
I built Vanilla, a private browser for iOS 26, in a few days using Claude Code. I'm a designer, not an iOS engineer, so the question was: how far could I get just by talking to my computer?
Further than I expected. But the most valuable part wasn't the code. It was having the real thing on my phone from day one, and noticing things a Figma file would never have shown me.
Asking before building
I knew I wasn't the right person to make implementation-level decisions, so I didn't try. Every time I wanted to add a feature, I switched Claude into plan mode and treated it like a research assistant. How do similar apps handle this? Which patterns does iOS expect here?
Claude would research competitors, read documentation, explain the trade-offs, and suggest an approach that fit the project. That time paid off far more than pushing ahead and fixing things later.
Adding privacy protection
Once navigation and search worked, I moved on to privacy. Same approach: in plan mode, Claude looked at how other browsers block trackers, read through blog posts, and proposed options that fit the scope. I settled on DuckDuckGo's Tracker Radar and EasyPrivacy, and used the same setup for ad blocking and hiding cookie banners.
It didn't work right away. Cookie pop-ups were hidden on some sites but not others, and some protections broke certain sites while working fine on the rest. I didn't step in. I let Claude iterate until it worked. Then it opened the simulator, ran the fingerprint test on Cover Your Tracks, and showed me the result.
Where prompting stopped working
For tabs, I wanted something like the iOS app switcher, similar to what Arc does. That was too ambitious, at least for the current models used at the time of writing.
I couldn't get the web view to animate cleanly in and out of the horizontal card grid. It was too custom a problem for Claude to figure out on its own, and it needed more hand-holding than I could give. After a lot of back and forth, I let it go.
I switched to ZoomNavigationTransition and a card-based grid. It worked immediately. That was the clearest lesson of the project: when an animation is very custom and barely documented, prompting your way to a good result is hard. Established patterns have far more written about them, and the models handle them much better.
Living with it
Because a working build was on my phone from the start, I could keep adjusting it every day.
Small bits of friction got annoying fast. Things that felt fine on day one felt off by day three. After a couple of days I toned down the haptics and tightened the spring curves, which made the whole app feel faster.
Liquid Glass was the other surprise. It didn't behave the way I expected. The glass picked up different colors from each website's background, and as you scrolled it kept adapting in ways that looked a little funny. When I hit moments like that, I'd loop in a more specialized agent through axiom:ask to work out what was going on, then tweak it until it felt right.
That's the part I'd never get from designing in Figma.
What I'd do differently
First, I'd set a stricter scope and clearer do's and don'ts in claude.md from the start. I lost time because Claude kept optimizing for older iOS versions and avoiding newer SwiftUI frameworks. At first it even assumed iOS 26 was still in beta.
Second, I'd set up Apple Docs MCP on day one. I only found it halfway through. Giving Claude direct access to Apple's docs and years of WWDC sessions made a noticeable difference.
Mockups show you how something should look. A build in your pocket shows you where it gets in the way.