Mobile Multiplatform: The Untold Story

Yuna Wang
@ Promoted
Published in
6 min readAug 3, 2022

Why you’ll probably have to rewrite your app using native tools anyway

Java AWT/Swing. Qt. React Native. We’ve been through this song and dance before. Every multiplatform UI library promises the moon. After all, who wouldn’t want two or three apps for the price of one? Unfortunately, as a developer, I’ve been on many teams that have regretted going multiplatform. Below, I’ll discuss some issues that many companies don’t take into consideration when committing to multiplatform libraries, and hopefully convince you, esteemed reader, that this decision isn’t so cut and dry.

Please note that I won’t be diving into the most well-known multiplatform issues such as performance, memory, and user interaction. Other authors have done a far better job than I could at researching these. Also, for many marketplaces, these performance issues aren’t actually important. I’ll stick to other important issues that I haven’t seen mentioned very often in mobile development circles.

Long-Term Technical Debt

If you’re using React Native, I bet there’s at least one utility function along the lines of Platform.isIOS(), Platform.isAndroid(), or the like. There may not be many call sites to these functions when your app is new, but these calls always seem to multiply as development proceeds.

By the time an app grows to any appreciable size or complexity, the amount of custom code required to handle situations unique to any single platform expands to the point where the notion of “write once, run anywhere” doesn’t apply as cleanly as it once did. For one thing, many interactions are handled differently on different platforms, such as media, purchases, and notifications. System permissions can be vastly different, too. Sometimes, it can be minor tweaks: a UI layout just doesn’t look right on iOS, or Android uses a different icon for sharing. It’s naive to think that you’ll never have platform-specific code in your app.

Fast forward a few quarters, and it all adds up. An app that once boasted a single “multiplatform” codebase is now replete with platform-specific if/else checks, or even entire components or subsystems that are platform-specific. This snowballs into tech debt that no one had predicted when the project started. If you start introducing more advanced technology into your app as you grow, such as augmented reality, then you can really find yourself in a bind.

At this stage, many companies find it easier to simply rewrite the app using the native tools on each platform. Also at this stage, unfortunately, the time it takes to rewrite your app and transition to native can be many times greater than an initial investment of building and maintaining two separate native apps. Maybe this will be an acceptable tradeoff when you reach this point in your app’s lifecycle, but even so, it’s a tradeoff that many developers are not aware of.

Finally, by way of circumstantial evidence, I’ve heard of several companies switching from React Native to UIKit/SwiftUI and Android SDK as their app evolves in complexity. There may be apps that have switched the opposite direction, but I don’t know of any high-profile examples. (There are plenty of large companies that use React Native, but I can’t find definitive evidence of any that switched to React Native from native tools. Please chime in if you know of any!)

Bugs, All the Way Down!

Every UI platform has bugs. The Android system has them, UIKit definitely has them, and SwiftUI is well on the way to writing many bugs of its own. To this end, whatever multiplatform library you choose will always increase the number of bugs that you must deal with in your ecosystem. Even if your library uses HTML/CSS to render UI elements, it still has to use native iOS or Android code in some capacity under the hood.

When you hit a bug that’s not in your own code, there’s the challenge of figuring out where it came from so you can find a fix or a workaround. This kind of bug-hunting can slow down development significantly. Things get even more complicated if your team writes its own UI library, too. This ongoing cost is difficult to budget for, and in many projects it manifests as both undesired behavior and technical debt in the form of “magic” UI code that works, but nobody knows why.

Native has its share of bugs, but multiplatform makes the situation far worse.

Maintenance

How is the ongoing support and maintenance of your multiplatform library? For community-based projects, how responsive are the developers? I’ve seen cases where we find the perfect open-source widget for our needs… except that it hasn’t been updated since 2016. If there isn’t a major corporation whose bottom line is impacted by the UI library in question, then it’s really a gamble as to how well it will be maintained in the future. Mobile OS updates can render third-party libraries obsolete very quickly, too.

Accessibility

Almost all multiplatform libraries have basic accessibility support, which is great news for users who need these features. Unfortunately, this is not enough for you, as a vendor. Despite the widespread adoption of accessible technologies, accessibility is still a source of potential litigation. If your app is not fully accessible in terms of screen readers, navigation, high contrast, large text, motion impairment, and many more areas, you might be opening yourself up to lawsuits under the Americans with Disabilities Act. Many organizations exist with the sole purpose of bringing about such lawsuits against the publishers of web and mobile apps. And I have heard of cases where they win judgments even against so-called minor or cosmetic bugs in apps that are otherwise fully functional.

The larger your business, the bigger the target you are to these organizations. Major corporations spends millions of dollars hiring experts and developing features to support accessibility. Does your multiplatform framework have you covered with more than just the basics? Does it respond to all system accessibility settings and interactions correctly?

Internationalization

Are there assumptions in the UI code about the directionality of text? Do layouts automatically reverse themselves when appropriate for RTL languages? Do really long or short strings break the layout in the UI? How about the display and formatting of dates, times, and other pieces of information with units? Some regions use different calendars altogether. Some languages display family names first, such as Chinese, Japanese, Korean, and Hungarian. I sure as heck wouldn’t trust any app that shows my Chinese name as “玉娜 王” instead of “王玉娜”. And that’s to say nothing about whether there’s been an audit for potentially offensive iconography. 👌🏻

This may be a moot point if you’re only planning to launch in a single region, but if you have aspirations of reaching out to a global market, your UI platform better be up to it.

Testing

As a conscientious developer, you’d never merge code that you haven’t tested on every platform that it’s supposed to run on, right? Or at least, you’d never ship it? It’s often tempting to think that your multiplatform library is supposed to take care of these annoying platform differences, but that’s not always the case. After all, something begat all those Platform.isXyz() checks in your codebase. Whether it’s the additional build and test time done by engineering, or extra cycles that QA pulls, you still end up spending time testing on both platforms that you would have spent anyways if you had gone with native.

Productionization

Setting up and dealing with your build system can be a significant time investment, and multiplatform doesn’t eliminate this requirement. And that’s even before the task of productionizing and submitting to App Stores. There are more headaches, too, if your app is rejected. These kinds of things can easily eat several hours or days of developer time around release cycles.

Summary

I’m not saying that you should avoid these libraries entirely. There are still good reasons to use multiplatform at the beginning: time-to-market, prototyping, developer familiarity. These advantages should be weighed carefully against the tradeoffs above, in addition to other, better-known tradeoffs. It’s not always 2 apps for the price of 1 — closer to 2 apps for the price of 1.75, and sometimes the margins are even tighter.

In my next post, I’d like to dive into instrumentation, logging, and debugging in mobile applications. These aspects are often overlooked in newly launched apps, and that’s exactly when they are most important.

Posts in the Series

  1. A Game of Phones
  2. Mobile Multiplatform
  3. Lessons Learned from Google Mobile: Apps Need Instrumentation

--

--

Yuna Wang
@ Promoted

Mistress of bad puns and mobile engineering at Promoted.ai. Former tech lead/manager at Google Maps for iOS.