Choosing the right cross-platform app framework

Mitchell Hayward

Published:
Last updated:

If you’re reading this, you’re probably thinking about building an app. No? Perhaps you’re looking at migrating from a framework like Xamarin, which will pretty much reach its end-of-life/support period once iOS 17 is released on the 19th of September (18th for those in the US).

Key considerations

There are numerous blog posts out there telling you things like “Top five cross-platform app frameworks”, but I feel like that kind of misses the point. Instead, a better question to ask yourself is “What am I building?”. That may seem like a captain obvious kinda thing to say, but hey, there’s beauty in simplicity. Once you understand what you are building, that gives you the power to assess all of these different cross-platform mobile app frameworks.

Theo (t3.gg) posted a video a couple of weeks back specifically talking about Flutter and where it’s application sits in the sea of mobile app frameworks. TLDR; it’s a bit niche. I wanted to take some of the points Theo was making, and extrapolate them so the choice for selecting a cross-platform mobile app framework is a lot clearer, and hopefully easier.

What are you building?

An absolute key factor to consider when building a mobile app is understanding exactly what you are building. By that I mean:

Expanding on a diagram Theo shared in his Flutter video, I’ve plotted out those two key questions and aligned them with technological approaches.

The cross-platform guide

Cross-platform mobile app guide

Framework alignment

See some examples below of where I think current frameworks fit in relation to the cross-platform guide:

Unity | Unreal Engine | Godot
Flutter
Android (Kotlin / Java) | iOS (Swift)
dotnet MAUI | React Native
Ionic
React | Vue | Svelte | Angular

Native features

What are native features? Native features are things that your app requests a mobile device to do, for example:

Hopefully that starts to paint a clear picture of what a native “feature” is. The more of these you rack up, the more you shift right on the cross-platform guide.

Native controls

We spoke about native features, what on earth is a native control? A native control is essentially a platforms version of a UI element. For example, in dotnet MAUI or React Native if I were to create a button in XAML or JSX it’d map directly to it’s platform counter-part (an Android or iOS button), meaning I’d get that platforms native control features out of the box (e.g. gestures).

Rendering

Flutter actually uses Skia (or Impeller) to draw components onto a canvas (as opposed to mapping directly to a platforms UI element implementation). Why? Well one thing that does offer is a lot of flexibility over how the UI looks, to someone unfamiliar with app development it may feel easier to create and design the look of a Flutter component (widget). The main drawback here is that you lose the native functionality that comes with the UI element you’re building. This makes it important to consider things like accessibility and gesture support when building widgets. It’s also important to note, because Flutter uses it’s own renderer, things like OS level UI (e.g. a permission dialog) are not rendered by the OS, but are instead “faked” in Skia/Impeller.

📝 Note

I stand corrected here, Flutter has full support to show OS level dialogs and prompts. I also find it important to clarify, that I actually enjoy working in Flutter and as of updating this post am actively learning it. The purpose of this article was to highlight when and why you might want to use certain cross-platform frameworks. That’s not to say that I’m 100% correct, after all these are just my thoughts on a page. If you want to use Flutter for any purpose, you are absolutely free to do so. In my honest opion, its developer experience is unparalleled and something I completely missed as part of writing this post! Some may call it overkill, but that’s actually okay - as long as you can deliver a good user experience with the tool that you have (and also have an enjoyable developer experience). After all, consumers rarely care about the tech products are built on, only that it meets their needs (and of course is performant). What is important for us developers is that what we build is maintainable, and intuitive/easy to work with.

Reference: Flutter permission_handler

What do I choose?

Ultimately the choice is yours, a framework is just a tool on our developer toolbelts used to achieve a set of user requirements. What is important is to ensure you choose the right tool. If you aren’t using a lot of animation, but want some native features it doesn’t really might not make sense to choose something like Flutter. Similarly if you need a lot of animation, it doesn’t might not make a whole bunch of sense to try and achieve that with something that doesn’t have it’s own rendering engine. If in doubt, refer to the cross-platform guide and work from there. Remember, with great power comes great responsibility.

References