What I learnt from porting a Production App from React Native to Kotlin to Flutter
A comparison of the top three mobile frameworks while porting an Android Launcher
Tl;dr : Each and every framework has it’s own strengths and weaknesses it depends on the context to … mehh I like Flutter the best :D read on why.
So I’m the maker of LessPhone Launcher (Formerly NoPhone cause trademarks :P ) and this is my experience while I ported my launcher through these three holy frameworks in the period of 6 months.
Tldr: Go with Flutter for all your mobile development needs and change to Kotlin if you are doing some really intense App that requires a lot of fiddling on the Native side. React Native had it’s time.
Here’s LessPhone https://play.google.com/store/apps/details?id=me.aswinmohan.nophone&hl=en_IN the app the story is about.
In June I launched LessPhone (no link here dummy, stop jumping around and read a complete article for god’s sake) on Product Hunt. It’s an Android Launcher inspired by(ahem ahem) LightPhone that aims to reduce your phone usage.
It would only allow you to select around 4 Custom Apps and once set as the launcher those four Apps are the only ones you can use.
When I first started working on LessPhone back then (June 2018) I chose RN for two reasons.
- It was the only framework I knew
- I didn’t knew anything else
I started my serious mobile development journey with RN(Ionic doesn’t count) around 2017. It was a little hard to set up and run but the development experience was pretty awesome. Writing UI using JSX that felt like HTML but with blazing fast experience felt really empowering. I was in love (with a framework duhh) for the first time. I preached it everywhere and talked with everyone how fast we could iterate while being on RN.
I never thought writing a launcher in RN would be possible but all it took was two lines of code in the AndroidManifest and some plugins. I released the MVP to the play store and Product Hunt. With the help and mentorship from the awesome people at Kerala Product Hunters it got to the fifth position, and after 2 weeks added the first Inapp purchase a dark theme and the dough started rolling in.
Pros of React Native
- Near Native Performance : The user wouldn’t be able to tell if it isn’t a native app without some introspection.
- Hot Reload : I think I’m spoiled by this. When I started with Kotlin that was when I realised how awesome this feature was. Instant changes but it was buggy so I had to manually shake the device for the menu to show up.
- Platform Inconsistencies : Since RN wraps native widgets the rendering was slightly different on different phones. Small enough to not justify the extra effort to fix them, big enough to make your users think how badly polished your app was.
- Size : This was not such a big issue that I was able to bring the size down of the app with builtin apk splitting and proguard shrinking.
- Bridge : This is an issue that I think would affect only a tiny fraction of the developer base. Since this was a launcher I had to get the list of installed Apps from the native side. When the App list was long the bridge crashed without giving any warning and it really affected my app rankings on the Play Store. They would stop promoting your App if your crash rate is more than 1.2% of your daily sessions. So daily downloads went like a wave.It was bad and I couldn’t debug it. Fortunately Peter Lazar pointed me in the right direction :D.
Adding up React Native gives a medium great Developer Experience with a medium great User Experience.
So the crash rate was pretty damn high around 3% and LessPhone was performing pretty bad. When I learnt that the culprit was the RN bridge, rather than trying to fix it, I thought I’d rewrite the entire thing in Kotlin.
Kotlin was the new kid in town, it was shiny and promised the reduction of the whole lot of the suckablity of the Android Java experience. I also wanted to get deep down into Native if I was going to pursue mobile development seriously. Also there was a clone of my app which was built in native, it was under 1 Megabyte and with stellar user experience.
I started with some tutorials on kotlin basics, started searching around on the web for resources. Kotlin was fairly new and resources where scarce. I started on the Udactiy Android course and bogged till the third chapter. The real breakthrough came when I started to do the complete App tutorials on YouTube.
I started implementing LessPhone in Android and whenever I got stuck asked Google and my good friend Irshad for help.
- Fast : The new app was blazing fast, we might think React Native as close to native and the performance will be unnoticeable. The difference can be felt from the first opening of the App to the end. It’s like seeing a pretty beautiful girl, we can’t say why she’s attractive it’s just we like seeing her.
- Small : With all the bells and whistles of size reduction and proguard the apk size of the react native app was 3.4mb, with kotlin it was down to 760kb.
- More Control : duhh
- No more errors : Just kidding, I was able to eliminate the previous download killing error but there were other lurking around the corner.
- Steep learning curve : Comparing with RN learning Native is not such a pleasant experience. There are a lot of things you need to keep in mind and the unneeded splitting creates a lot of unnecessary overhead.
- Boilerplate : The amount of boiler plate is just immense, and you’d understand me the moment you write a list-view in RN and Kotlin.
- Hot Reload : I missed the hot reload on React Native, don’t tell me about the hot reload feature with Kotlin, does not come close.
- Pretty Low Level : Working with a high level framework as RN takes care of a whole lot of the hairy part of the platform. Underlining text is a breeze in RN whereas you need to do a lot of hoops in Kotlin.
Kotlin was mediocre development experience with oh my god it’ s so fast and slick User Experience.
Also Unbox Therapy reviewed LessPhone on his channel and that took the downloads over 70k overnight, so great time.
So LessPhone is doing well, money is rolling in, users are somewhat happy and I hate the code base.
In the months I gave the ability to select four custom apps, but some users wanted more and some wanted less. So the solution was to set the number of custom apps customizable (thanks Sooraj for the idea :).
The code in Kotlin worked like a charm but was like Frankenstein had a baby with a .., you get the point hideous. I didn’t understand what I did and why I did that, and I couldn’t think of any sane way I was touch that code. So I did what any self respecting developer would do, complete rewrite from bottom up.
Around the time Flutter became mainstream, everyone was talking about it, raving how cool it was and how it would solve a lot of the problems with cross platform development and RN.
I checked it out and was put off the first time I saw it . Come on no JSX and we have to write a whole of nested function like thingy for UI, no thanks.
But you can’t bitch about something if you haven’t tried it even once. So i bit the lead and started learning flutter.
Even though Flutter was relatively new Google was doing a pretty good a job with the documentation and resources. There was already a Udacity course, stellar documentation and a whole suite of awesome tooling. I started with people building complete Apps with flutter on YouTube and followed those.
- Consistent Rendering : Since Flutter draws it’s own widgets there’s no need to pray that your app is going to consistent across devices. It’s just going to look like it was intended to.
- Stellar Tooling : Flutter had the best suite of tools I had ever used. Even for use cases that I thought no one would ever have the Flutter team had taken that into mind.
- Developer Productivity : The ease with which we can ship features is mind blowing. Everything works together to help achieve this level of productivity.
- Dart : JS should learn from dart, static typed and mature. The community and the libraries reflect the trend. Most libraries play well and I haven’t had a library fail on me yet.
- Material Widgets : The builtin widgets are just awesome. There’s no need for external packages with implemented UI components. The inbuilt ones are high quality and easy to work with.
- Less Boilerplate : Way less than Kotlin, everything fits inside well defined components.
- Excellent Documentation and Community : Google has done the best job with the documentation. Everything is documented with examples. Also there are core engineers on the flutter team hanging around on issue tracker and forums willing to help.
- Near Native Performance : The performance is better than RN since flutter compiles to native arm code but worse than Kotlin (by a tiny teeny margin)
- Hot Reload : This is how hot reload should be.
- Google : Google created and maintains Flutter, Dart, and Android. That’s vertical integration at it’s best. So they all play along well.
- Lack of Libraries : Dart is new and this is an issue with that newness. The library support is growing rapidly but has yet to match RN which can reuse the existing JS libraries.
- Build Size : Out of the three platforms Flutter had the biggest APK size, around 6.55 Mb and I can’t find any way to reduce it.
- Lack of Best Practices : The community is new and coming together. There are a bunch of state management and architecture patterns and there’s no recommended one (yet).
Since the pros outweigh the cons well, the current version 3.0.6 runs on Flutter and the users are loving it. Some have complained about the performance hit but also that you have to really look hard to find it.
I am shipping features as fast as possible and flutter is helping really well. Although with the lack of libraries I had to write Native code a little bit, but I think that’s because writing a launcher is not on the Flutter team’s important checklist.
So Flutter Awesome Developer Experience and Awesome User Experience.
All articles like this end with stating that all three frameworks are awesome and that you should go with whatever you want, but that’s not why you came to read this article right.
Go with Flutter for all your mobile development needs and change to Kotlin if you are doing some really intense App that requires a lot of fiddling on the Native side. React Native had it’s time.
In case you want to see LessPhone : https://play.google.com/store/apps/details?id=me.aswinmohan.nophone&hl=en_IN