Back to Blog

Flutter vs Native: Why I Still Reach for Native on Most Mobile Projects

#flutter#mobile#native
Flutter vs Native: Why I Still Reach for Native on Most Mobile Projects

Flutter is good, and I’ve used it on a few client projects that genuinely needed both platforms on a tight budget and timeline. But for most of my mobile work now, I still go back to native — Swift for iOS, Kotlin for Android. Not because I’m against cross-platform on principle. More about where the breaking point usually shows up.

Platform APIs that don’t wait around

New features from Apple or Google usually land in the native SDK first, and only later (if at all) get bridged into Flutter through a community plugin. I ran into this directly once: a client project needed iOS Live Activities (the lock-screen widget that shows real-time progress), and at the time the Flutter plugin for it was half-baked — several edge cases weren’t handled, and the maintainer wasn’t updating it much. I ended up writing a native module myself to bridge it into Flutter, which got me thinking: if I have to write native code anyway for one important feature, why not just go native from the start.

Performance and feel that lands right

Native widgets automatically follow platform conventions — animations, gestures, haptic feedback — without extra effort on my part to imitate them. Users usually can’t articulate why, but they can feel the difference between an app that’s native and one that isn’t. iOS scroll physics, for instance, has a distinct rubber-band character; Flutter can approximate it, but it takes manual tuning that comes free with the native framework.

Debugging without an extra layer

When something breaks in a weird way, I’m debugging at the same layer as the platform itself, without an extra abstraction that can make stack traces confusing. I felt this hard chasing a memory leak in one app — in Flutter, I had to jump back and forth between the Dart heap and the native heap to find the source, because Flutter’s own rendering layer (Skia/Impeller) isn’t always transparent about where a leak is actually happening.

Team size and project scale

When I’m working solo and targeting just one platform first (say, iOS only, to validate a product), there’s no strong reason to carry the overhead of a cross-platform framework. Flutter’s initial setup is fast, but once a project needs more and more platform-specific features, maintaining two mental models — the Flutter widget tree plus native code for whatever isn’t covered — starts feeling heavier than just going native from the start.

Flutter still makes sense when the priority is shipping to both platforms quickly with a small team and a tight budget, and the features aren’t too platform-specific — something like an MVP or internal tool that just needs to work, not feel premium. But when I have the time and the project will be maintained long-term, native is still my default. The cost of learning two languages and two toolchains is real, but for me it’s cheaper than the cost of debugging an abstraction layer that isn’t always cooperative.