Every founder who reaches the "let's build a mobile app" stage hits the same fork: Flutter, React Native, or fully native development with Swift on iOS and Kotlin on Android. There's no universally correct answer here, whatever each framework's marketing pages imply — the honest answer is "it depends," and the useful part is knowing exactly what it depends on. This piece walks through the tradeoffs that actually decide it: performance ceiling, access to bleeding-edge platform APIs, how native the UI feels, hiring and team reuse, and the long-term cost of one codebase versus two. Work through those five and the right stack gets obvious fast.
Flutter: One Codebase, Rendered by Its Own Engine
Flutter compiles a single Dart codebase to native ARM code and draws every pixel itself through its own rendering engine (Skia, with Impeller replacing it on newer platform versions) rather than delegating to each OS's native UI widgets. That's the core thing to understand about it: Flutter isn't translating your code into native components, it's painting its own components that happen to look like native ones. The payoff is consistency — a button looks and animates identically on iOS and Android because it's literally the same rendering code — and hot reload makes day-to-day iteration genuinely fast. For most business apps (lists, forms, navigation, moderate animation) performance is close enough to native that users never notice a framework underneath.
The tradeoff shows up in two places. First, matching each platform's evolving design language — new system fonts, dynamic type behavior, platform-specific gestures — takes deliberate extra work, since Flutter doesn't pick those up automatically the way native code does. Second, the Dart hiring pool is smaller than JavaScript's or Swift/Kotlin's, though experienced mobile or backend engineers tend to pick it up within days. We used Flutter for FitPulse, a fitness app that needed offline-first workout tracking and Apple Health / Google Fit sync delivered by one team on a tight 14-week timeline — a single codebase was a big part of hitting that deadline.
React Native: JavaScript/TypeScript Driving Real Native Components
React Native takes a different approach: your JavaScript or TypeScript code renders actual native UI components — a real UIView on iOS, a real Android View — through a bridge, increasingly the newer JSI-based architecture rather than the older async bridge, which removes a chunk of the historical performance overhead. For teams that already run a React web product, this is the strongest argument in its favor: no new language, no new mental model, and often real reuse of state management patterns and business logic between web and mobile.
The ecosystem is enormous. Most third-party SDKs — payments, analytics, push notifications — ship a React Native wrapper before a Flutter one, simply because RN has been around longer and has a bigger install base. The cost is variability: for anything the core framework doesn't cover, you're depending on community-maintained native modules of uneven quality and upkeep. You'll occasionally need someone comfortable dropping into native Swift or Kotlin to patch a module or wire up a capability the JavaScript layer hasn't caught up to yet.
Native Development: Swift for iOS, Kotlin for Android
Fully native means two separate codebases, two toolchains, and — realistically — two sets of engineers who each specialize in their platform. In exchange, you get the actual ceiling: same-day access to every new platform API Apple or Google ships, the true native performance floor for animation-heavy or compute-heavy work (AR, real-time video processing, complex custom gestures), and a UI that matches platform convention by default because you're using the platform's own component library, not an approximation of it.
The cost is real, and it's not just the initial build. Every feature gets built, tested, and shipped twice, on independent release cadences, so feature parity between iOS and Android drifts unless you actively manage it. Two codebases also mean two sets of bugs, two app-store review cycles, and roughly double the ongoing maintenance surface. Native is the right call when performance or platform fidelity is the product — a camera-first app, deep HealthKit/Health Connect integration that a plugin doesn't cover well, anything latency-sensitive — but it's expensive insurance to buy for a product that hasn't yet proven it needs it.
The Factors That Actually Decide This
Performance ceiling
For CRUD-heavy business apps, dashboards, booking flows, and most consumer apps, Flutter and React Native are both fast enough that users will never notice the framework underneath. The gap widens at the extremes: heavy custom animation, real-time camera or AR processing, and games benefit from native's direct access to the GPU and platform frameworks. If your app's core value proposition depends on that kind of performance, weight this factor heavily. If it's a fairly ordinary set of screens talking to a backend, it barely matters.
Access to bleeding-edge platform APIs
When Apple or Google ships a new capability — a new sensor, a new system API, a new privacy or permissions model — native code gets it on day one. Flutter and React Native get it once the framework or a plugin author wraps it, which can take anywhere from days to months depending on how niche the API is. If your product depends on being an early adopter of new platform capabilities, or on deep integrations with platform or third-party APIs that plugins don't cover well, that lag is a real cost, not a theoretical one.
UI consistency vs. platform-native feel
Flutter's paint-everything-itself approach gives you pixel-identical UI across platforms, which is genuinely valuable for brand consistency but takes deliberate work to feel at home on each OS. React Native, by rendering real native components, tends to feel native by default, at the cost of some cross-platform visual drift. Native wins here by definition — but for most B2B and consumer products, users spend their time on one platform and rarely compare the two side by side, so this matters less in practice than teams assume going in.
Hiring and team reuse
Team composition should drive this decision as much as the technology itself does. A team with strong React or TypeScript skills — especially one already running a web app — gets real leverage from React Native: shared patterns, sometimes shared code, and a larger existing hiring pool. A team without an existing JavaScript bias, or one that prefers strongly-typed, structured tooling, often finds Dart and Flutter's more opinionated setup easier to standardize on. Neither pool is as deep as platform-specific mobile hiring used to be, since cross-platform frameworks have pulled a lot of newer mobile engineers away from native specialization.
Long-term maintenance: one codebase vs. two
This is the cost founders underestimate most. One codebase means one CI/CD pipeline, one test suite, one release process, and one team fixing one bug instead of two. Two native codebases mean roughly double the ongoing engineering cost for every feature, indefinitely. That compounding cost is the strongest argument for a cross-platform framework unless the product has a specific, provable reason to need native's ceiling.
Flutter vs. React Native vs. Native, Side by Side
| Dimension | Flutter | React Native | Native (Swift + Kotlin) |
|---|---|---|---|
| Language | Dart | JavaScript / TypeScript | Swift (iOS), Kotlin (Android) |
| Codebases to maintain | One | One | Two, independent |
| Rendering approach | Self-drawn (Skia/Impeller) | Real native components via bridge/JSI | Native platform UI, no abstraction |
| Performance ceiling | Very good; near-native for most apps | Very good; native for UI, JS for logic | Highest possible |
| New platform API access | Delayed until framework/plugin support | Delayed until framework/plugin support | Immediate, day one |
| UI feel | Consistent across platforms; needs tuning for native feel | Native by default; some cross-platform drift | Fully native by definition |
| Hiring pool | Smaller, growing | Large; overlaps with web React talent | Two specialized pools, generally most expensive |
| Typical time to market | Fast, one build to ship both platforms | Fast, one build to ship both platforms | Slower; two builds, two QA passes |
| Best fit | Consumer/business apps needing visual consistency and a lean team | Teams with existing React/web investment | Performance- or platform-API-critical products |
A Decision Framework You Can Actually Use
Instead of picking a stack because it's trending, work through these in order:
- Your team already writes React or TypeScript for the web. React Native reuses that investment directly and shortens the ramp-up more than any other factor on this list.
- You need one team shipping both platforms on a tight timeline, with visual consistency mattering more than platform-native nuance. Flutter is built for exactly this — it's why we reached for it on FitPulse's 14-week build.
- The product's core value is deep platform integration, top-end performance, or same-day access to new OS capabilities. Budget for native and for two teams; treat the extra cost as insurance the product actually needs, not a default.
- You're validating demand before committing serious engineering budget. Start cross-platform, ship, learn which platform and which features actually drive retention, and reconsider native later if the data justifies it.
- The audience is consumer-facing and platform "feel" is part of the brand experience — this shows up a lot in fitness and consumer apps — weight React Native's native-component rendering, or native development itself, more heavily than you would for an internal or B2B tool where function matters more than platform polish.
None of these decisions are permanent. Teams migrate frameworks, rewrite specific modules natively, and adjust as the product proves out what actually matters to users — the stack you launch with doesn't have to be the stack you scale with. What matters more than picking "correctly" on day one is working with an engineering partner who's actually shipped in all three stacks and will tell you honestly which one fits your constraints, not just the one they happen to know best. If you're weighing mobile app development options for your product, we're glad to walk through your specific requirements — get in touch or request a quote and we'll give you a straight answer.
Need this built, not just explained?
We do this work for clients every week. Send us your situation and we'll come back with a scope and a price range within one business day.
Get articles like this monthly
Engineering and AI notes from real client work. One email a month, unsubscribe anytime.