Why not native?
It feels like this is an ever-changing and moving target of an answer. Originally the answer was to save devs/teams time, with the core promise being “write once, run twice” (outside of small platform-specific wrappers). Depending on the solution chosen, that also had the added benefit of allowing full control over the UI/UX down to the pixel, rather than being locked into each native platform’s widgets, and being consistent across platforms.
Over time this moved on (see Cordova originally, then 5-ish years later Flutter and React Native) to other options that offered the same thing. A new class also came to be that allowed you to target native widgets from one shared codebase, at the cost of pixel-perfect control.
Then came the age of AI: within the last year, two notable companies12 have announced that they are going back to two native mobile apps, using AI to speed up the process and keep the two apps in sync. Funnily enough, Shopify had declared React Native the future of mobile back in 2020, and Airbnb already sunset React Native in 2018. However, this being a possible industry trend does not mean that it’s a good thing - anyone remember when NoSQL was going to replace every database?
Flutter: Google’s black sheep
Created around the same time as React Native, it stuck to the paradigm of allowing pixel-perfect control of the UI. It provided a home for Google’s proposed JavaScript replacement language, Dart. This turned out to be a good thing, as it allowed deep integration with the framework, making it smooth and easy to use. While still not being the recommended platform for Android, it retains a notable place in terms of Google’s investment in it, most notably writing their own rendering engine, Impeller, to get away from Skia’s issues and allow more low-level rendering control. However, given that it’s not the recommended solution, and Google’s long history of Killed by Google projects, it does raise an eyebrow.
Compose Multiplatform: Flutter with more steps
Compose Multiplatform serves as a good option for native Android devs, using Kotlin. Similar to Flutter, it renders everything on its own canvas, though it still uses Skia. Compared to Flutter, it released much later and doesn’t offer as much direct integration, while adding Kotlin Multiplatform’s Gradle setup on top of the usual Xcode wrangling for iOS.
React Native: the web’s darling
Unlike the previous two options, which draw their own pixels, its main argument was all about being truly native, allowing web devs to make native mobile apps while sharing some components with their websites. In practice, sharing React components with your website meant you were forced into using limited functionality (no <div>s, and only a subset of CSS), or restricting bits from mobile. Also, JavaScript performance problems led Meta to create the Hermes engine to address this.
Skip: a silver bullet?
It seems only fair, with a title like that, to put all the disclaimers first.
- Maturity: 3 years old
- Low number of contributors: 9
- A company/project with no apparent profitability, having gone free and open source and relying on sponsorships
With all of the disclaimers out of the way, why use this over any other option? Skip is on the native widget side of the fence, rather than pixel perfect. However, unlike the others, it converts your Swift/SwiftUI code into Kotlin/Jetpack Compose for Android. This allows you to avoid the pains of wrapper libraries, etc. You can just #if os(Android) the platform and then write native code/use native libraries without having to care.
It also allows you to be truly native on each platform. Because it’s iOS/Swift first, the iOS side is just a normal Xcode project, without the weird build errors, etc. that come with the territory of using any of the other options. Additionally, it allows small package bundles, as it’s using native widgets and code compiled to native, so there’s no need to ship a JS engine, for example.
Worst comes to worst, if Skip ceases to exist, you are left with two native apps that you can maintain however you want. Also, as new UI/UX comes to each platform (see Liquid Glass for example), one can just use it, rather than needing to wait for the framework to reimplement it (for pixel-perfect strategies) or libraries to wrap it, etc.
So, which shade of insanity?
It seems like every option here is a compromise, it just comes down to which compromise you can live with. Flutter and Compose Multiplatform give you pixel-perfect control, but you’re stuck waiting on them to reimplement each platform’s UI. React Native gives you native widgets, but you have to ship a JavaScript engine with it. Going full native means building everything twice, AI or not.
For me, Skip is the most interesting option, despite the disclaimers. Its worst case is ending up with two native apps, which is where the companies leaving cross-platform are heading anyway. That said, if your team already lives in React, React Native is probably the path of least resistance, and if your app needs to look identical everywhere, Flutter is the more established pick, Google’s track record aside.
So at the end of the day: pick your poison.
](https://blog.terraqueststudios.net/posts/cross-platform-mobile-frameworks/foggy-mountain-summit.jpg)