Against cross-platform development

Drew CrawfordNews

The siren call of “write once, run everywhere” is one of the more pervasive myths in computing.  The goal, of being able to write the software once and have it work on other platforms, with no or minimal development effort, is a very attractive one, given the time, expense, and risk of software projects.  Unfortunately, it is largely a myth.

To discover this, we need to look back all the way to C, the original “universal” programming language.  Many forget that the original goal was to create a standards-based, cross-platform development environment.  C/C++ is still in wide use today, but everyone will tell you there is no such thing as true cross-platform C/C++.

To rectify this situation, Java was created, the next savior of cross-platform code.  While Java is still widely used (particularly in the enterprise and a strangely Java-yet-not-Java implementation on Android), Java has also failed to live up to its name as a truly cross-platform application development framework, and it was recently deprecated for the Mac and is being largely abandoned as a desktop platform as well, apart from continued use in special niche open-source software and enterprise software.

The new siren song is cross-platform mobile development, the ability to write the code once and have it work on many platforms: Android, iOS, Windows, Blackberry, and more.  Unfortunately this is even more of a pipe dream than cross-platform desktop development, which has seen botched “solutions” dozens of times over its history.  Let’s examine some of today’s mobile cross-platform contenders.


HTML5 is a standards-based loose collection of web technologies that let you build applications that run in a web browser.  HTML5 is mature enough that tool and platform support is pretty good, at least relative to the stability of some of the proprietary platforms.


Like any high-level language, HTML5’s JavaScript suffers from performance problems.  Mobile technology is still at the stage (unlike desktop development) where performance matters substantially.  Technologies we take for granted like garbage collection, while making the programmers’ lives much easier, suffer unacceptable performance penalties that make graphics, animations, and transitions sluggish and the UI appear unresponsive.  Even if you’re not doing complex calculations, basic UI suffers to the point where your users will notice.

We’re still at the infancy stage in mobile performance.  The computing power of an iPhone is, quite literally, the size of a postage stamp (the device is all screen and battery, very little horsepower).  Software advances like the Nitro Javascript Engine are interesting only because the engine they replace is so terrible, not because the new engine is particularly good.  Without an enormous breakthrough in battery life design, HTML5 development will likely continue to have poor performance for the foreseeable future.


HTML5 offers only very limited visibility into device capabilities.  If you want to send push notifications, use CoreAudio, perform advanced GPS or location-based tasks, run in the background, record or edit video, audio, access the users’ Photos or Contacts library, do any sort of data visualization, responsive UI drawing, leverage existing frameworks, do any kind of number crunching or performance-sensitive calculation, display maps, utilize the contacts database, or store much data on the device, you will need to use native code instead of an HTML5 application.  If you don’t need any of those things, an HTML5 app might have enough power to do what you want–but in that case your app isn’t really very exciting to begin with.


If you’re interested in distributing your app through the Apple App Store, you need to write native code.  If you want to leverage the iTunes billing system to do in-app purchasing, subscriptions, etc., you need to write native code.  While it is possible to wrap an HTML5 app in a thin layer of native code for this express purpose–unless you already have invested in an existing HTML5 app, it’s almost always cheaper to go the native route to begin with.



PhoneGap is a small set of libraries that essentially offer a little bit of native glue to access native features while still basically writing an HTML5 application.

Tool Support

Because PhoneGap is so new, the tool support is terrible.  The state of PhoneGap debugging is absolutely awful. There is no debugger, and as good as you will get is printing debug statements to a log somewhere and/or trying to debug in a desktop web browser that behaves differently.  The debugging burden for a system like PhoneGap is enormous, which translates into huge productivity losses.


Because PhoneGap uses underlying web technologies, performance is the same as HTML5, i.e. not ready for even the most basic applications, at least according to the standards of most iOS users.


PhoneGap adds a lot of native features to HTML5, but is still missing key features  like Contacts access, maps, any kind of fine-controlled media playback, calendar APIs, messaging APIs, access to native UI controls, and many more.


Historically, PhoneGap users have had problems getting their apps approved for distribution, although it’s not clear whether or not this is still the case.  The official wiki describes how to hide PhoneGap from Apple and then states “This is not a guarentee, [sic] many users have been reporting rejections after removing all phonegap references.”


Appcelerator’s Titanium is a purportedly cross-platform development solution covering desktop and mobile development for iOS, Android, perhaps Blackberry, Windows, Mac, and Linux.

Tool Support

The free tools do not have debugging support.  To get debugging and other basic developer comforts, you need to spend $500/developer/year.  Unfortunately I was not able to find anyone who had paid for the subscription to evaluate the effectiveness of the premium tools.


Titanium bills itself as a “native” app development environment.  Unfortunately, this is simply not true, at least not by any meaningful definition of the term.  It is only accurate to say that Titanium uses proportionally more native code than other platforms and exposes native controls, meaning faster UI response times in many common cases.  It does not mean that your entire app runs at native speed, since it still relies on the same JavaScript that powers HTML5 web apps, which suffer terrible performance problems.


We’re aware of no problems related to distributing Titanium-based apps on the App Store.

Cross-Platform Compatibility

Because Titanium tries to be a “more-native” platform, it has many cross-compatibility problems, as native UI controls simply work differently on Android vs. iOS, and there’s no one-to-one mapping that will work perfectly, in spite of Appcelerator’s best efforts.

The problem that you then end up with the situation where I developed for iOS but didn’t test it on Android. I had faith that if it worked properly on iOS then it would still work fine on Android presuming I didn’t use any “platform specific” functionality. The problem is that it very quickly gets to a situation where everything doesn’t work properly on Android and it requires lots of time to fix the issue. Cross-platform? Not really.

If you’re technical, I would highly recommend reading Sam Moffatt’s entire review, as he does an excellent job relating the dozens and dozens of little snags in developing the most simple application in Titanium.  He documents inconsistent behavior between platforms, documentation that is completely missing or (worse) misleading, etc.  Titanium ends up being a passable development platform for certain situations, but completely fails in its effort for cross-platform compatibility.

So What’s the Right Way?

The right way is to write a separate native application for each platform.  This requires high time, effort, and expense, but it is the only way to provide a high-quality experience (i.e. one worth paying for) to your users.

If a platform is worth supporting at all, it’s worth supporting right.  Bad app experiences damage your brand and cost you valuable reputation with your customers.  Unfortunately we see many potential clients led astray by the lure of cross-platform development, only to end up with buggy software that runs poorly on any platform.  For many applications, true Objective-C-based native development is the clear best choice.

If you’re interested in letting us develop your native iPhone or iPad project, get in touch today.