· 5 min read Posted by Kevin Galligan

Why You Should Build Mobile Apps With Compose

If you are building a mobile product, you are probably considering React Native, Flutter, or some flavor of HTML. Maybe you’re even considering fully native apps. If so, you should learn about Compose Multiplatform. Compose provides full cross-platform efficiency, and can be as native as you need, minus the risk.

Modern Mobile Development

The modern smartphone era began with iOS in 2007, closely followed by Android in 2008. For the first several years, if you cared about the quality of your apps, you would build native apps. Nobody was excited about building the same app twice, but cross-platform was too much of a risk.

Native was the smart choice.

Today, most new apps are built with something like React Native or Flutter. Not so much when the app itself is the product, but when mobile is necessary for your business needs. While the various cross-platform tools have their compromises, the end result is generally good enough.

Compose Multiplatform is a relatively new option, offering key advantages that improve quality and remove risk for mobile product development. It may not be on your radar now, but it will be soon. Here’s why.

Chat with Touchlab

Every project is unique. Want to find out if Compose Multiplatform is right for you?

What is Compose Multiplatform?

Without getting too technical, Compose Multiplatform is built on top of Kotlin Multiplatform (KMP). KMP is designed to work directly with the native iOS and Android platforms, as opposed to other cross-platform tools, which attempt to hide and replace the native platform itself.

Compose is the UI framework portion of the stack. It is the primary native UI for Android, which has been extended to many other platforms, including iOS.

Why Compose Multiplatform?

Compose Multiplatform allows you to build mobile apps with the benefits of cross-platform technology, minus the critical risks of cross-platform technology, and allows you to make those apps as native as you need them to be.

Can you build cross-platform apps? Yes. Can you build native apps? Yes. You can also have something in between. It is fundamentally different technology.

Cross-Platform Efficiency

Using Compose and KMP, you can build Android and iOS apps with a single codebase. In other words, it is a cross-platform app.

The quality and maturity of cross-platform tools, however, can have a dramatic impact on efficiency. React Native and Flutter are mature tools. Compose Multiplatform is relatively new. However, Compose itself is not. It is the primary UI technology for Android. Compose itself, and the tooling behind it, are built by the Android team at Google. They have invested heavily, over several years, to make sure Compose is an amazing platform for mobile development.

There is no foreign, third platform being used, as with all other cross-platform options. That is a critical point to understand.

One aspect of Compose being Android-native is that Android developers do not need to completely relearn how to build apps. This is a win for existing teams, and for finding capable developers.

As Native As You Need

If you could build a native app without the complications of native development, you would. A good native app is preferred by everybody. Me. Your users. You. We are all mobile users, and a good native app is just a better experience.

Native development, however, has many complications. Cost, siloed teams, feature parity drift, etc. For most apps, the quality difference between cross-platform and native is marginal, but the development difference is not.

For most apps, the value of native does not justify the cost.

Compose Multiplatform provides a new option. It can be as native as you need it to be.

To start, Compose and Kotlin are Android’s primary frameworks. An app built with Compose and KMP is native on Android. There is nothing cross-platform about it.

On iOS, a Compose UI performs well, but does not inherently have that “native look”. Like other cross-platform options, you can use themes to approximate a native experience on iOS.

But Compose Multiplatform is different. It can do something the other options cannot.

As mentioned, Compose and KMP work directly with the native platforms. That means you can blend fully-native iOS UI with Compose, while using the same support code underneath.

That means, you have have a cross-platform iOS app, a fully native iOS app, or a blended UI anywhere in between.

A hypothetical example

Feedback from product owners and users suggest you should have built a native app on iOS. Do you need to rewrite the app? Absolutely not!

In most apps, users spend almost all of their time on a few core screens. Less-common areas of the app may be rarely or never used by most users. Settings, informational dialogs, secondary features, etc. You can simply reface your primary screens on iOS with native implementations, without replacing the support code underneath them.

If analytics says that your users spend roughly 90% of their time on the core screens, keeping in mind that your Android users already have a fully native app, that means your combined user experience is almost entirely native. With an almost entirely single codebase.

And, you can do that incrementally.

Low Risk

Cross-platform frameworks have always had the same critical risk:

  • You need to decide how you will build your app, cross-platform or native, before you start
  • You won’t know if you made the “right” decision until the “end” (even then, you won’t really know for sure)

The “end” could be late in the development cycle, or worse, bad feedback from your users.

“Was this the right decision?”

Whether your app is cross-platform or native, this might be a nagging question.

If your app is cross-platform, you might wonder if the reception would have been better with native. The result of a cross-platform app is never perfect. Was it really better overall?

The Risk Cliff

For cross-platform, we call this the Risk Cliff. You made a decision at the base of the mountain. You’ve climbed all the way up. At this point, if where you are isn’t where you want to be, you don’t have many good options. There’s just a big cliff on the path forward.

Why the cliff? Because the fix for a cross-platform app that should have been native is a rewrite. Of both apps. That decision is usually preceded by time spent trying to tweak the cross-platform build to be good enough. Extra cost.

The Risk Cliff was a real problem years ago. Cross-platform apps really weren’t great. The quality of cross-platform tools has increased dramatically. There is still that same cliff. You’re just much less likely to need to deal with it.

Compose Multiplatform does not have that cliff.

Additionally, cross-platform development is not perfectly efficient. It is not “two apps for the price of one”. You don’t get the quality of two native apps, and building a cross platform app certainly takes more effort than building either app natively.

The myth of cross-platform efficiency

Cross-platform has never been, and still is not, “two apps for the price of one”.

Two Apps

This issue should be obvious. You don’t get two native apps. You get two good enough apps. If those two apps are indeed good enough, this isn’t really an issue. However, cross-platform proponents have often implied that the basic 2-for-1 equation. Practical reality falls quite short of that.

Price of One

Non-trivial apps always require features and integrations that are more efficient when they are built native. Cross-platform tools attempt to homogenize the specifics of Android and iOS, but they can only do so much. At the end of the day, an app runs on a real device.

Some native platform integrations are simply different. Not just the API, but the flow and constraints in how they are implemented. No cross-platform tool (even KMP) can entirely avoid this. This factor will always make “1” into something larger than “1”. Specific cross-platform tools, and how well directly they interface with the native platform, can impact how much larger “1” is. Because Compose and KMP were designed to interact directly with native platforms, they can minimize that impact.

UI is another issue. For performance reasons, some complex UI will struggle with a cross-platform implementation. That varies from framework to framework. However, some UI components have native implementations available. Trying to rewrite them with cross-platform UI is simply not an option.

For example, maps. These are complex, performance-critical components, that have native implementations. Obviously writing a cross-platform map UI from scratch would be a terrible idea. You need to integrate the native map implementations into the cross-platform tool.

All modern cross-platform tools provide some mechanism to integrate native UI. However, the overhead and difficulty involved varies significantly between cross-platform tools. Again, because Compose and KMP were designed to integrate directly with the native platform, no other cross-platform tool could possibly be better at doing this. Both from the perspective of developer effort, and additionally the runtime performance of the integration.

Other cross-platform frameworks don’t just hide the native platform. They remain removed from it at a technical level. In technical terms, calling the native platform is an RPC (Remote Procedure Call). Although the target of the call isn’t “remote” in the sense that they live in the same process sandbox, the calls need to be made between incompatible runtimes. Data needs to be serialized, and often calls are made through message passing.

In less technical terms, most cross-platform frameworks don’t play well with others. They are their own world. Communication outside of that world is a strict process that involves overhead.

Compose and KMP operate directly within the native app runtime. In the case of Android, again, Compose and Kotlin are the tools you would use for a fully native app. For iOS, Kotlin is presented to Swift as if it was just more Objective-C or Swift (use SKIE, btw). Native calls aren’t RPC calls.

With Compose Multiplatform

A cross-platform app is not “2” native apps, and it costs more than “1” to build. With Compose, the Android app is actually native. On iOS, how native you want the app to be is flexible. You can expend more effort, and get closer to native, or not. Because of how KMP and Compose integrate with the native runtime, while you can’t have “1”, you get as close to “1” as possible.

If you built two native apps, was that extra work really worth it? Now you have two different apps, requiring two different types of devs. The apps need to be kept in sync as the apps evolve.

Compose Multiplatform doesn’t entirely remove the question. It just removes the weight of it. You can build the app with a cross-platform UI. If you think it should have some native UI, you can swap that in, precisely where it’s needed.

That swap can happen at any point in time. During development, the team can integrate native components. If the finished product doesn’t feel quite right, you can reface critical portions of it with native iOS UI.

The argument for Compose Multiplatform is not simply that the tech is inherently better than all other options at producing a cross-platform app. The real difference is, you’re not forced to make risky, up-front decisions.

Chat with Touchlab

Every project is unique. Want to find out if Compose Multiplatform is right for you?