Image Credits:Juhari Muhade (opens in a new window) / Getty Images

When do you go native?

The hardest decision in app development is often the very first one

So you’re a startup founder. Or you’re in charge of a new project at a big company. (Or maybe you just imagine being either of these things.) And you suddenly realize: you have to make a whole slew of massive decisions right now, based on imperfect information, which will reverberate for months or years, and may spell the difference between success or failure.

Among the most dreaded and dangerous decisions are the technical ones. Your web stack. Your cloud provider. Your datastore. But it’s fair to say that the most contentious, lately, is for projects which involve a smartphone app. There, the biggest question of all, the one which must be answered before any work is done, and the one which will probably hang over you for years, is: do you go native?

What that means is: do you build separate native Android and iOS apps, each from scratch in a native language, almost certainly meaning two development teams? Or do you use one of the many tools which promise you two apps for the price of one?

You can of course just build one app at at time. That makes sense if iterating swiftly to product-market fit is more important than doubling your initial addressable market. But if you do so with a native app, be aware you’re implicitly deciding to have two development teams, and two separate and out-of-sync codebases to maintain, somewhere down the road.

Choose your technologies (and your developers) wisely, and you will be able to move deftly, hire (relatively) easily, iterate quickly, and pivot gracefully. Choose poorly, and you’ll be burdened with technical debt that weighs you down until you’re barely able to fix bugs, much less roll out new features.

Speed matters. Cost matters. The long-term benefits of a single codebase are obvious — as are the costs of subpar apps which wind up costing far more than your initial gains. You could conceivably be betting your whole company on this decision. So what’s the right answer?

This is a decision I see a lot. For context, I’m the CTO of HappyFunCorp, and we wrestle with this decision multiple times a year, as we design and architect new apps for clients, or do major overhauls or existing ones. So I can tell you with great confidence that the answer is: “It depends.”

Techcrunch event

Join 10k+ tech and VC leaders for growth and connections at Disrupt 2025

Netflix, Box, a16z, ElevenLabs, Wayve, Hugging Face, Elad Gil, Vinod Khosla — just some of the 250+ heavy hitters leading 200+ sessions designed to deliver the insights that fuel startup growth and sharpen your edge. Don’t miss the 20th anniversary of TechCrunch, and a chance to learn from the top voices in tech. Grab your ticket before doors open to save up to $444.

Join 10k+ tech and VC leaders for growth and connections at Disrupt 2025

Netflix, Box, a16z, ElevenLabs, Wayve, Hugging Face, Elad Gil, Vinod Khosla — just some of the 250+ heavy hitters leading 200+ sessions designed to deliver the insights that fuel startup growth and sharpen your edge. Don’t miss a chance to learn from the top voices in tech. Grab your ticket before doors open to save up to $444.

San Francisco | October 27-29, 2025

The Other Options

OK, fine, I’ll unpack that a bit. But first let me warn you away from a whole family of potential solutions; the ones wherein the “app” is actually JavaScript running in a WebView with a thin native wrapper, i.e. PhoneGap and its descendants: Cordova, Ionic, etc. I have personally had the misfortune to work with several of these and I have never had anything other than a terrible experience. Do yourself a favor: stay far, far away. Progressive Web Apps are more interesting, but they aren’t really “apps” per se, and they’re so limited (especially on iOS) that they’re excluded from this analysis.

This still leaves you with multiple options. If you have a C#/.NET development team, then your answer is easy: Xamarin (which was purchased by Microsoft a few years ago.) Xamarin is very good, but if you don’t have a .NET team, this is probably a bad time for them to learn a whole new environment. (For historical reasons, .NET tends to be a lonely island far from the archipelago of other platforms, i.e. developers tend to be firmly either .NET or not.)

Then there’s Flutter, which comes from Google, and is so very, very Google. Only Google would insist that you learn an entire new language, which it built in-house and nobody else uses, in order to write its cross-platform apps — that being Dart. Sure, learning a new language is not that big a deal, but your first project in a new language tends to be … how to put this exactly … a little crude. Do you really want your app to also be your dev team’s first project in a whole new language? Also, it’s very, very new: 1.0 just shipped in December 2018. Do you really want to be on the bleeding edge?

Probably not. Which may be a shame, because otherwise Flutter offers a lot of really interesting things. Instead of using the standard native look-and-feel, it has its own rendering engine, so Flutter apps can easily look very different from “standard” Android/iOS. Given its current immaturity and idiosyncracies I can’t in good conscious recommend it today, unless you really really need your own stand-out look and feel … but I can recommend keeping an eye on it.

The One You’ve Heard Of

And now to the monster of the space, the 800-pound gorilla, the de facto standard, the Godzilla stomping on native apps’ Tokyo: React Native. If you don’t match one of the above two niches, then if you’re talking about cross-platform, single-codebase app development, then — especially since its awkward licensing situation was sanely resolved — it pretty much goes without saying that you’re talking about React Native.

And with very good reason. It’s written in JavaScript; it’s no exaggeration to say that almost every software developer knows at least some JS nowadays. It has a thriving ecosystem, a plethora of plug-ins, and if your project involves a web site, an Android app, and an iOS app — as so many do — React Native offers the potential of using the same code across all three, if you use React proper on the web … and if you architect your code correctly.

A no-brainer! you might think. And many did. There was a huge shift towards React Native in 2017 and the first half of 2018. But then came the backlash. Airbnb dropped a bombshell post explaining that “we are sunsetting React Native at Airbnb and reinvesting all of our efforts back into native” because “numerous technical and organizational issues […] added frustrations and unexpected delays to many projects.” A month later, Udacity chimed in: “The mobile team here at Udacity recently removed the last features in our apps that were written with React Native.”

Et tu, RN? Where did it all go wrong?

It’s worth noting that Airbnb, in particular, had a very … unusual … context. The Airbnb app has roughly 900 screens; yours probably does not. React Native was only used on a small part of their app(s), rather than universally. Similarly, at Udacity, they used it for a new feature set. This makes no sense to me at all: clearly if you’re going to go RN, then you go all in, or else, as Airbnb put it themselves, “we wound up supporting code on three platforms instead of two”.

That said, there were more specific concerns. JavaScript, unlike the native languages, is untyped; as a rule of thumb, this is OK when initially writing code, but causes problems when refactoring. You can add another layer of abstraction to get typed JavaScript with TypeScript … but another problem with RN is that beneath the hood it’s running in a JavaScript environment, with a bridge to native APIs. This affects performance, especially on iOS, and the more layers of abstraction you’re running in, the more subtle issues might bubble up across them. For instance, capturing stack traces when debugging can be a lot harder in React Native.

Furthermore, while RN can call out to arbitrary native code, it takes time for its libraries to catch up with new native features. A more insidious problem: while there are plenty of open-source “native modules” which offer plug-and-play native functions to React Native, they’re usually written by developers who are either better with Android or better with iOS … and thus one implementation is weaker and buggier than the other.

The Takeaway

Does this all seem to have made the problem worse, not better? Does it all seem complex and esoteric and require the weighing of umpteen subtle factors by multiple expert adjudicators in order to figure out which is best? I’m not going to lie: context always matters. Your particular answer might be different. But at the same time, fear not, there is in fact a simple rule of thumb here.

That is: use React Native if you’re mostly just wrapping an API. The more your app is effectively a UX skin around server-side logic, rather than performing complex functions itself, the more suited your app is to React Native. You still probably won’t develop two React Native apps in half the time it would take to write them natively. It might be closer to 2/3 the time than 1/2. But you’ll still save time, and you’ll have a common codebase down the road, some of which might even help power your web site. On the other hand, the more your app is doing as an app — the more code that needs to run on the phone, rather than a server — the more likely you are to thank yourself down the line for building native from scratch.

Whatever you choose, though, you need to commit to it. Combining React Native with existing native code is something very like the worst of all worlds — no wonder both Airbnb and Udacity recoiled in horror from their attempts. Make your decision, stick with it, and move on to the dozen equally critical ones which await you next. Good luck, founder and/or leader. And remember that old military truism: any decision is better than no decision.

Topics

, , , , , , , , ,
Loading the next article
Error loading the next article