How I Build For Proprietary Platforms and Sleep at Night

I’ve spent the last three years of my life helping web developers build apps for iOS and Android. As such, I hear this sentiment a whole lot:

I think Henrik’s tweet is representative of an opinion that many in the greater web community hold: that native ecosystems are proprietary and closed, and therefore, that you should avoid building on those platforms unless it’s absolutely necessary.

In this article I want to convince all web developers, not just Henrik, that it can make good sense to build apps for iOS and Android, and that you can do so without compromising your beliefs in the purity of the open web. I’ll base my argument on three points:

  • 1) That building for native doesn’t mean you have to stop building for the web.
  • 2) That frameworks like React Native, and NativeScript, which I work on, allow you to build for native while giving up very little of your soul.
  • 3) That building for multiple platforms expands your horizons as a developer — and that’s a good thing.

Let’s start by looking at how the web and native can coexist.

Web or Native — Why Not Both?

Many developers assume that choosing to build a native app means you’re choosing not to build for the web. They cite companies like Uber, which has a prominent native app, but doesn’t seem to have a significant presence on the web. This doesn’t have to be the case though.

In his article “Mobile Web vs. Native Apps or Why You Want Both”, Luke Wroblewski argues that building for both native and the web makes a lot of sense, and provides some excellent data to prove his points. First, Wroblewski shows native’s biggest advantage is usage, as people spend an order of magnitude more time in native apps than in web apps:

Wroblewski then shifts his focus to the web, and shows that the web’s biggest advantage is its reach, or its ability to reach out to a large user base:

This quote from Wroblewski sums up these charts nicely:

“The Web is for audience reach and native apps are for rich experiences. Both are strategic. Both are valuable. So when it comes to mobile, it’s not Web vs. Native. It’s both.”

Web apps and native apps each have advantages, and it’s up to you, as a developer, to determine how to leverage the unique characteristics of each platform to build the most compelling experience for your users. That ideal experience might be web only, but if you take a moral stand and build only for the web, you’re ignoring a massive opportunity that native apps offer.

I can give many examples of companies that build interfaces for both platforms well, but my personal favorite is Amazon’s Kindle service, as it has taken plenty of my money. For example, suppose you want to read “The 5th Wave” (which I highly recommend, by the way—the book is way better than the movie). If you Google “the 5th wave book”, Amazon’s listing is the first organic result:

Amazon’s web app is taking advantage of the web’s reach. By having a Google-crawlable web app, Amazon maximizes the chances of new users finding and buying “The 5th Wave” through them. If this book listing was only in Amazon’s native app, it stands to reason that considerably fewer users would find the listing, and therefore considerably fewer would purchase the book as well.

However, after you purchase the book the experience is quite different. Although you can read Kindle books on the web, Kindle’s native apps provide a far more polished experience by tapping into the unique characteristics of the various devices they provide apps for. Amazon’s iOS Kindle app, for instance, has a persistent login so I never have to remember my password to read; it lets me download and integrate dictionaries and encyclopedias; it allows me to lock my screen orientation and brightness from directly within the app; it lets me read books aloud via text to speech voices already installed on my iOS device; and a whole lot more.

The key thing to note here is how well Amazon’s web presence and native presence complement each other. Amazon doesn’t try to implement the same user interface twice—once for native and once for the web — instead they leverage the web for reach, so that their listings are seen by as many people as possible, and leverage native apps to provide a rich reading experience.

And that richness is really important. Amazon certainly could’ve built their reading app exclusively as a web app, as most of the functionality needed to implement it is supported nowadays. However, for Amazon, building with native code gives them the performance they need to create the best possible reading experience. And that difference in experience, even if it’s a small benefit, is enough to keep more users satisfied and willing to purchase books through Amazon in the future.

In fact, although this article has defined “native” as iOS and Android apps, the best place to build might be for an entirely different type of hardware. Personally I find the reading experience to be less than ideal on my phone, and use Amazon’s dedicated Kindle devices to do most of my reading, as it has a screen that’s optimized for reading, and a far longer battery life than mobile phones.

It’s not hard to think of other successful services that take a similar approach to dealing with the web, native, and even other types of hardware — Netflix and Hulu for watching shows, Instagram for pictures, Pandora/Spotify for listening to music, and so forth. One could even argue that the reason some of these services are successful in the first place is because they provide software that runs on the hardware their users have.

As a developer it’s worth thinking about your service and what platforms to target to offer the absolute best experience for your users. That experience might be web only, however, if you have a subset of functionality that would benefit from tying into the capabilities of modern devices, it makes good business sense to provide that experience for your users.

Native Apps Barrier to Entry

Although native apps have the ability to provide this compelling experience, they’re also a heck of a lot harder to build, especially for developers that only have experience building for the web. Historically, your average company couldn’t afford to take the time and hassle needed to deploy to these various platforms — after all, not all of us operate at Amazon’s scale.

However, this is where I feel frameworks like NativeScript and React Native are significantly changing the mobile landscape, as these frameworks significantly lower the barrier to entry that has long existed to build for iOS and Android.

The single biggest advantage of using React Native or NativeScript is rather obvious: you use JavaScript to write your app’s logic rather than native code such as Objective-C, Swift, or Java. This not only means that you’re saved the hassle of learning new programming languages, it means you also have the opportunity to share some code, and a lot of tooling between your web, Node, and native apps.

Just to give you a small taste of this, for my personal NativeScript apps I use JSHint and JSCS for code listing, Mocha and Chai for unit testing, utility modules such as Moment and lodash, and npm scripts for kicking off common tasks. (Here’s a full app implementation, if you’re interested.)

This ability to use familiar tooling means you’re significantly less coupled to the proprietary platforms that you are building for. If you choose to build an app with NativeScript or React Native, and years later building for iOS and Android no longer makes sense for your product or company, you’ve been spared some of the hassle of learning new languages, tools, and development environments.

For developers there are also fun new challenges that you take on when you choose to build for multiple platforms. Like, how you can architect your JavaScript code so that it’s usable in both your web and native apps? Should you share your model objects on all platforms? Your services? Utilities? Images? How can you automate these processes to maximize your productivity and the speed at which you can deploy features to your users?

There are also interesting ways you can blend your native and web apps together to increase your code reusability. All native platforms include the concept of a Web View which is basically a mini browser that you can embed into your native apps. A lot of companies are playing with interesting ways of mixing web content into native applications with this approach. For instance, Mobify has a project called Astro that provides some conventions around placing web content in native apps. In NativeScript, we provide a simple <WebView> control that makes embedding web content from local or remote sources trivial.

But although performing some tasks with these frameworks can be trivial, there is one final thing I want to make clear: although frameworks like NativeScript and React Native indeed lower the barrier for building native apps, especially cross-platform ones, that barrier is still there. Once you choose to build a native apps there are some things you can’t get around learning. But, I think that’s a good thing.

Building for Multiple Platforms Broadens Your Horizons

If you’ve been a developer long enough, you’ve probably heard the term “polyglot developer” thrown around at some point. Succinctly, a polyglot developer is a developer who has the ability to code in multiple languages or programming ecosystems. The idea is, a developer that has experience in multiple languages is better able to select the appropriate tool for the job, or, at the very least, knowing multiple ways to solve a problem can help developers write code in a more efficient and maintainable way.

Regardless of how much value you put in having polyglot experience, most developers acknowledge that there’s some benefit to having experience in multiple programming languages. And I would argue that the same benefits exist for working in multiple platforms.

The web is great, but it’s only one of many ways to build user interfaces. The web does some things well, and the web does some things poorly, but it’s hard to have a basis for those judgments until you’ve tried to build on alternative platforms.

I’ll give you an example.

You don’t have to look hard to find people ridiculing web developers for using web UI frameworks such as Bootstrap or Foundation. Yet, a Bootstrap/Foundation development experience—an experience where a collection of high-quality user interface and layout elements is available out-of-the-box—is more or less what’s directly available in the iOS and Android SDKs.

For instance, on iOS you can drop a UINavigationBar and UITabBarController into your app and have something that immediately looks decent. To give you a sense of what that looks like in action, take a look at the NativeScript code below, which creates both a UINavigationBar and a UITabBarController under the hood:


  <!-- NativeScript renders this as a UINavigationBar on iOS -->
  <!-- NativeScript renders this as a Toolbar on Android -->
  <ActionBar title="My App" />

  <!-- NativeScript renders this as a UITabBarController on iOS -->
  <!-- NativeScript renders this as a TabView on Android -->
     <TabViewItem title="Tab 1">
          <!-- contents of the first tab -->
     <TabViewItem title="Tab 2">
          <!-- contents of the second tab -->


Those fifteen lines of markup build this decent-looking starting point for both an iOS and Android app:

On native, a lot of the basics to create something that looks good are built directly into the platform, but building something similar to this on the web takes a fairly considerable amount of code. Web components aim to provide this sort of experience for the web, where you can drop in simple elements and have then look good by default, but they’re still a ways off from being commonplace. That leaves us in a bizarre situation where it’s easier for beginners to build basic native UIs than basic web UIs.

I’ll give another example of where the web could learn a thing or two from native mobile platforms, and that’s list views. The iOS UITableView and Android android.widget.ListView APIs let you display enormous lists of data on the screen, and take care of memory management for you automatically. There’s no need to resort to virtual-DOM-like hacks to workaround a basic limitation in the platform.

Because of this robust performance, common UI features like endless scrolls and pull-to-refresh are several orders of magnitude easier to implement in native apps when compared to the web. For instance, in NativeScript I can build a native app that displays a list of 100,000 items—an app that performs spectacularly—in 20 lines of code.

Here’s my UI declaration, which NativeScript renders using the UITableView and android.widget.ListView controls internally:

<Page loaded="loaded">
  <ActionBar title="My App" />

  <!-- NativeScript renders this as a UITableView on iOS -->
  <!-- NativeScript renders this as a android.widget.ListView on Android -->
  <ListView items="{{ list }}">
      <Label text="{{ number }}" />

And here’s the short bit of JavaScript I need to populate those list views with 100,000 items:

var Observable = require("data/observable").Observable;
var ObservableArray = require("data/observable-array").ObservableArray;
exports.loaded = function(args) {
  var pageData = new Observable();
  var list = new ObservableArray([]);
  for (var i = 0; i < 100000; i++) {
    list.push({ number: i });
  args.object.bindingContext = pageData;
  pageData.set("list", list);

With that code in place, here’s a quick look at what the resulting app looks like when I put it through its paces:

To build a UI like this on the web I would need to bust out non-trivial JavaScript and DOM shenanigans — and even then I couldn’t come close to the polish that native OSs provide for free. There’s a reason that most feed-based apps, like Facebook, Twitter, and so forth, choose to build native apps: because native controls allow you to provide a much richer experience in an app than you can on the web. To businesses, those richer experiences lead to more engagement, and ultimately lead to a stronger bottom line.

My point in this section is not to compare web and native, because I could also bring up a long list of pain points inherent to native development — non-trivial deployment processes, arcane provisioning steps, dealing with app stores, etc. My point is: stepping outside of your comfort zone and developing apps in a completely different ecosystem, even if it’s just a little sample app for personal use, can give you a whole new perspective on how approach user interface software engineering. If you’re a web developer, this perspective can give you ideas on how we can improve the open web to benefit everyone.

How I Sleep at Night

So to wrap up, yes, I build apps for proprietary platforms, but I don’t personally see that as some great evil; I see it as a calculated business decision made to provide the best possible experience for my users and my company. Sometimes I build for the web because of its reach, and sometimes I build on native to get a rich experience, but most commonly I build for both in a way that leverages the unique characteristics of each platform.

As a developer, the unique challenge of deploying to multiple platforms fascinates me, and toying with different ways to share code, share tools, and share ideas – all while maintaining a first-class experience on all platforms — is what keeps me motivated to stare at a computer screen for 8+ hours a day.

Fighting for the open web and building native apps don’t have to be competing ideas. You can build for native, and use what you’ve learned to help build the web. I personally have a far better sense of what the web does well, and what the web does poorly, after spending several years working with Android and iOS. If you’re a web developer that would like to give building native apps a shot, set aside an hour or two and go through our NativeScript Getting Started Guide; it’ll walk you through the basics of building a native app, and give you a taste of what it’s like to be a native developer.

Related Resources

Header image courtesy of Jean L.

[cm_ad_changer campaign_id=121]