Cross-platform frameworks are tempting. One codebase, two platforms, faster delivery on paper. We've used them. We know the pitch. Here's why we still reach for Kotlin and Swift first.
The 80/20 problem
React Native and Flutter get you 80% of the way there quickly. The remaining 20% — deep OS integrations, hardware access, custom animations, background processing — takes longer to wrangle through an abstraction layer than it would natively. That 20% is usually the part that makes an app feel right.
Platform conventions matter
iOS users expect things to work a certain way. Android users expect something different. Gestures, navigation patterns, typography, spacing — the platform has opinions, and users have internalized them. When you abstract the platform away, you tend to end up with something that fits neither perfectly.
Maintenance compounds
Cross-platform frameworks ship updates. The underlying platforms ship updates. When they don't agree, you're blocked. We've seen projects stall for weeks waiting on framework support for a new iOS version. With native code, you're in control.
When cross-platform makes sense
We're not ideological about it. If you need a simple CRUD app on a tight budget, a shared codebase makes complete sense. But if you're building something people will use daily — where performance and feel are part of the product — we'll push for native.
That's the kind of work we take on.