Should you use native or Flutter for your next app

For a while now I’ve been alternating between writing apps in flutter and Android native, and the decision of which app to write is more difficult than ever.

As flutter becomes more popular with developers, the 3rd parry libraries become better and the missing pieces are built. Still, before jumping into flutter head first, I’d like to compare some of my experiences developing flutter apps with my experience writing native apps.

Flutter — The good

Cross platform

Flutter is, as anyone considering writing an app in it would know, a cross platform framework. Mostly used so far for writing iOS and Android apps, it also has upcoming support for web. An app I’ve recently converted from iOS / android to web suggests this is going to be an entirely different way of writing web apps and with far more reuse than compared to react / native.

UI & Animation

Building a UI in flutter uses a declarative UI syntax, this is similar to react or even the new swift UI, and the up and coming jetpack compose for Android. Whilst this seems at the moment more like a personal preference than a solid point, most people using a declarative UI seem to prefer it, find it easier to develop in quickly and find it easier to build custom or bespoke UI components that can be reused.

For comparison, if you had to build a calendar screen from scratch in the android world and if you were to create a custom view component you’d likely find it a huge task, whereas building it in flutter is a much simpler. In its essence, android and ios native are both built with the idea that if you want to build a UI, you already have all the widgets you need — and the bits you don’t have, a few people will be able to build them for you. Flutter is built with the idea that developers want some good defaults, but also the ability to easily develop their own custom components.

Another thing that’s difficult to quantify is animations — my experience to date, is that animations are a lot easier in flutter than in native.

Hot reload

Colleagues of mine that are work solely on iOS projects don’t use storyboards or xib files, but instead build the UI in code and re-build every time they want to see a change. In native android, the story is a bit happier with UIs built in XML at least having a solid preview, but to really see the UI in action you still need to re-build and deploy. This is where hot-reload adds real benefit — when you save your code, it re-runs. The amount of time waiting for builds is drastically slower over the course of a whole project.

RxDart, Streams and BloCs

Not wanting to re-write many points explaining the BLoC pattern, reactive programming or dart’s use of streams, suffice to say — the combination is an excellent architecture for writing applications and at the very least is equal to MVVM

Flutter — the bad

Dart

Maybe I’m being un-fair, after all — until recently, a year ago I was writing primarily in Java, but Dart is not kotlin. Whilst it is a perfectly fine language, and it’s the main reason we are able to use hot-reload, it’s not (yet) as nice or succinct as writing in kotlin or swift.

Another issue with dart is its lack of adoption. In theory, you can write backend functions with it so you can share code between front and backend, in practice you’ve very little options for hosting or using services like aws lambda.

Packages

Whilst there is a huge increase in packages available for dart, and the dart package manager is lightweight and easy to use, it still lacks a certain maturity that leads to random and frustrating breaking changes. As an example, if package A depends on package B and your app relies on both — you need to upgrade both. Whilst it sounds benign in theory, in practice it means that you can have real issues managing your packages.

While we’re on the subject of packages, another shortcoming is the sheer number of some of them. For example, there are as many libraries for implementing the BLoC pattern as there are developers using said pattern. I’m sure in future there will emerge a few that are used by everyone, at the moment it’s a little overwhelming.

And staying on packages, it’s still hard to find packages to do everything. If you’re creating an app with Firebase as its backend, you’re in luck as there are the flutter fire plugins. Say however, you’re using auth0 or aws cognito or some other backend system with official support from the provider, you’ll find that there’s no official plugins for flutter (yet)

Platform channels

Part of this is an issue with documentation, but the cross platform development does need a way of calling ‘native’ code to fulfil any short comings of the framework, and in flutter these are called channels, and they are — at best — adequate. Once you’ve deciphered the documentation about them, you’ll find that calling a native function from dart involves calling a function by its ‘name’ and doing an if-statement on the native side e.g.

await platform.invokeMethod('getBatteryLevel');

Then on the native side

MethodChannel(flutterView, CHANNEL).setMethodCallHandler { call, result ->
// Note: this method is invoked on the main thread.
if (call.method == "getBatteryLevel") {
val batteryLevel = getBatteryLevel()

if (batteryLevel != -1) {
result.success(batteryLevel)
} else {
result.error("UNAVAILABLE", "Battery level not available.", null)
}
} else {
result.notImplemented()
}
}

Which just feels a bit dirty.

Where native is just better

Jetpack

This is an Android specific one, but something that has appeared in the last few years is a concerted effort by Google to make Android development easier — enter compose. The combination of databinding, view model, live data, coroutines, workmanager and room (database) has meant that threading, databases, updating the UI dynamically, background tasks and handing a separation of concerns between UI and logic is incredibly easier — and I would say easier than in flutter.

Data, Serialisation & Networking

On a similar note, we have an abundance of tools in native iOS and Android for talking to the network, (de-)serialising models from json, and storing them locally. There are tools in flutter, like this one for json and networking

and some great libraries, as yet, nothing feels quite as good as retrofit or the built in tools for swift. Similarly, with the database, we have SQLite, but nothing quite as good as Realm or Room (yet..)

Testing

Unit, UI and integration testing in swift is hard — the tools you get in the native platforms for all of the above, from scrolling in a UI test, to mocking a back end server or even seeing code coverage is far better in the native language.

Swift UI and Compose

Many of the things we’ve talked about loving flutter for building UIs are soon to exist in the native platforms in the shape of compose and swift UI. It’s hard to say at this point how crucial this will be — and adding to the cross platform thing, would it not be better to write some multi-platform kotlin for your logic, and get the native and performant UI from the platform you’re writing on? It’s too early to say on that one, but it’s certainly worth keeping an eye on for the future.

Discussion & Conclusion

The purpose of this post is to decide what the best approach is for developing your next app, so here are my opinions on the matter.

If your app is mostly UI, choose flutter.

If you’re building an app where the main purpose is to look pretty, to have nice animations — and you don’t mind that your app looks similar on iOS as on Android, go for flutter. If the data you’re presenting is fairly straightforward, the offline and synching you need to do are managable with the tools available in flutter, and you have no need for really custom things like siri, Bluetooth, VPN configuration or NFC — choose flutter. This is what it’s best for

If your app is mostly logic, choose native

If you have an app where the UI is fairly straightforward, but where you’re doing lots of maths, maybe using cryptography, storing complex data or anything in a similar vein, go for native. You’ll be a lot less likely to find insurmountable problems and there’s far more support for the issues you do encounter.

If your app is cross platform, choose flutter

This is my vaguest if, but if you have an app that you want to be basically the same on iOS and Android, you might want it on web and you might want a desktop version — go for flutter. There are obviously other things to consider with this that you need to weigh up. Say your app integrates with ‘stripe’ for payments; what percentage of development is that? If it’s a huge amount, then the time saved from implementing it using the officially supported libraries and tutorials probably outweigh the time saved in writing an iOS and Android app separately. If it’s a small percentage, then the time saved writing one UI might outweigh the fact that you need to dig in to platform channels to use the SDK.

Another note on this, is that this is much less of a consideration if your backend takes care of all the complexity, and you’re just going to try and integrate directly with the server. The time taken to write your integrations in swift and kotlin are probably lower than if you’re going to write it once in dart. It also means you only need to re-write it once if you change the API, and also dart is a lot more forgiving on data changing than its strongly typed counter parts — a json response parsed with a non-nullable kotlin data class will not respond well to that field being null, whereas dart has a good chance of limping on.

I hope you enjoyed your article, I’m really looking forward to your comments as I’m interested in hearing your own thoughts on whether or not to write a native or flutter app.

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Sailpoint ServiceNow Ticket creation for automated provisioning applications

First RESTful API — Turing School

2020: A Year to Remember and to Forget

CS371p Spring 2022: Daniel Cai

Should we all embrace systolic array?

Builder Pattern with Java Lombok

Getting started with Raspberry Pi GPIO and Python

The project is incredibly cool!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Daniel Llewellyn

Daniel Llewellyn

More from Medium

Flutter Stack Weekly — Issue #4

Flutter + Firebase setup on Android & IOS

How to Finish Current View/Activity In Flutter?

MVVM Design Pattern in Flutter