
Flutter vs React Native: Why We Choose Flutter on New Projects
Most teams argue this one by comparing feature lists. We have been shipping mobile apps for over a decade and our preference is settled: Flutter on new projects.
This article explains why, without dismissing React Native. Both are mature, and we have production work on React Native too. But when either tool can do the job, the details decide.
First, a common misconception
React Native does not run inside a web view. Plenty of people conflate the two, but the tools that use a WebView are Cordova and Ionic. React Native renders real native components.
The bridge that used to draw criticism is also gone. Since version 0.76, the new architecture is the default and the serialisation layer between JavaScript and native has been replaced by direct calls. So "React Native is slow" is an outdated claim.
Our preference does not rest on those old criticisms. The real reasons are different.
1. Its own rendering engine, identical UI everywhere
Flutter draws the screen itself. The Impeller engine produces every pixel rather than borrowing the operating system's stock components.
What that means in practice: the screen your designer handed over looks the same on an iPhone and on an older Android device. The manufacturer's own UI layer, the OS version and the user's font scale setting do not break the design.
With solutions built on native components this is not the case. The same code looks different across platforms, and closing the gap means writing platform-specific fixes. Where an enterprise client cares about brand consistency, that work accumulates.
We saw the payoff on Sportez: one design system, two stores, almost no platform-specific patching.
2. Method channels: no package to wait for
This is where the difference matters most.
Sooner or later a mobile project needs access to something specific on the device: a custom Bluetooth peripheral, a corporate authentication SDK, a piece of industry hardware.
In Flutter you write the native side yourself through a method channel. You implement the piece in Kotlin or Swift and expose it to Dart. The contract between them is yours.
The alternative approach starts by looking for a community package. If one exists, good. If not, you either write it or fork something unmaintained. Even when a package exists the questions continue: when was it last updated, does it work on the new OS release, is the maintainer still active.
On one project that is a small difference. Across ten projects it becomes a meaningful difference in risk.
3. A shallower dependency tree
In Flutter most things arrive inside the framework: navigation, state management options, animation, form validation, theming.
In the JavaScript ecosystem each of those is a separate package, and each package brings its own dependencies. A mid-sized app can end up with hundreds of transitive dependencies.
Every dependency is a maintenance liability: a security advisory, a version conflict, an abandoned package. On an app that will live three years, you carry that weight.
This also matters for whether the client's own team can maintain the app after handover.
4. Version upgrades break less
Flutter upgrades tend to go more calmly because the core capabilities come from one source. With fewer dependencies, the "one package updated and the others broke" chain happens less often.
On a project delivered in eight weeks that difference is invisible. It shows up in the third year's maintenance bill.
When we recommend React Native
There are clear cases, and it is worth being straight about them.
Your team already knows React. This is the strongest reason of all. Teaching Dart to a six-person React team is slower than letting them use what they know.
You are modernising an existing native app in stages. React Native's support for embedding screens inside an existing native shell is better established.
You need to ship updates without waiting for store review. Updating the JavaScript bundle remotely is an advantage with no direct equivalent in Flutter.
Sharing a mental model with the web team matters. Using the same component logic on both sides is a real gain for some teams.
When to skip both
If your app is fundamentally a real-time game, a video editing tool or heavy augmented reality, build native. Both cross-platform tools are the wrong choice for that work.
For everything else, meaning the business apps with forms, lists, maps, notifications and sync that make up the majority, either one is sufficient.
In short
The question is not which is better. Both work.
We pick Flutter on new projects because it guarantees UI consistency, because we do not wait on a third party to reach a native capability, and because the codebase we hand over carries a lighter maintenance load.
If your team knows React, or you are modernising an existing native app in stages, React Native may be the right call. What decides it is not the framework itself but your context.
If you want to talk through this decision for an upcoming build, bring your team's current skills and the device capabilities the app will need. The answer usually falls out of those two.