Using Flutter in a real-life application with 200k downloads
I’ve been running a real-world service for 6 months using Flutter, so I thought it’s be a good time to write down the background of why we chose Flutter and it’s impressions.
About our App
Our company is running a service for car lovers called CARTUNE (available only in Japan). Below are some screenshots from the app.
Screenshot with the red toolbar is the Android version and the one with the bottom tab is for the iOS. The screenshots here are all taken on Android machine (switching the flag for iOS screenshot).
Link to the news on Techcrunch JP: Next challenge of the creator for “MixChannel”, a “car” community “CARTUNE”, raised 110 million yen
Discussion points and the reason of the choice
I decided to use the cross platform development SDK supporting both Android / iOS for fast development. Although I had an experience developing for both Android / iOS, it is still hard to develop separately for both OS’s with a small number of people.
I reviewed Flutter / React Native / Xamarin at the time and finally chose Flutter, but there were several points we considered as follows.
Flutter uses Dart to write the code. The language felt like Java in the first impression. It was static typing and since async / await was supported, it seemed like it would be easy to write asynchronous processes.
I think C # used in Xamarin is also a nice language.
As for performance, I didn’t see any problem with any of the SDKs.
Flutter is compiled into native ARM code for both Android / iOS. I also tried out the Flutter Gallery from the Flutter team and got the feel that there seems to be no problem in performance.
Xamarin compiles on iOS natively, but on Android it seems to be running on Mono VM (if it was native compilation, I would have done a bit more research on it…).
Flutter has a wide variety of UI Widgets supported on the framework itself.
React Native and Xamarin uses the native UI (right?).
Thanks to this, Flutter had no difference between OSs related to the UI (there are places where behavior and appearance has been intentionally changed in Android / iOS by Flutter) and we expected to see a decrease of those situation where we will suffer with the difference between the OSs.
When I was doing the research (summer, 2017), there weren’t a lot of libraries etc. for Flutter, and the situation was that I needed to implement myself when needed. However, Flutter’s Widgets were very rich, and it seems that there would be no particular problem to implement the UI, since it is just about combine them (this was actually true until now).
React Native has a lot of developers using it, and it was very attractive to have lots of libraries.
For Xamarin, I had a memories that I fought hard at NuGet when I tried using it for a small apps a long time ago, but I do not know in detail.
Connecting to the native code
I considered about those cases where a feature was required which can not be written using Flutter by all means, and if it can be solve by writing the OS native codes.
On Flutter, platform specific functions (such as camera and position information) need to be called from the platform side. In these cases, the feature can be implemented by platform native languages (Java for Android, ObjC / Swift for iOS). For these cases, it is the same as developing on the platform standard, so you can use any libraries available in the world.
Also, from the platform native point of view, Flutter itself is just a single view with full screen display (the Flutter UI is drawn by GPU through this view). I tried installing and confirming whether it is possible to use Flutter and platform native UI one screen, just like a hybrid. I learnt that it is better not to use this mixing method, and we didn’t use it in our product. I just confirmed that it actually works.
When it became inevitable, it was important for us that there’s always a work around to implement anything by calling the code from the platform side in an RPC like style.
Building the UI
Flutter defines the UI by creating a Widgets tree within Dart. This is very comfortable. Since it is written as a code, it is easy to switch the UI according to the conditions.
Since Flutter has complete control of UI, I did not have any issues related to the difference of the OSs. Some UIs have different default values on Android / iOS (i.e. center-of-toolbar (iOS), left-justification (Android), transition of screen transitions, etc.) so that it will be close to the appearance and behavior of each platform standard, but you can unify them by specifying the options explicitly.
Flutter offers a wide variety of Widgets, and UI can be created with a combination of them, so there was no need for third-party UI library for that purpose.
“Fast hot reload” which officially states is true without any exaggeration. You can reloaded in less than 1 second.
The app can be reloaded in less than 1 second, not only for small samples, but also for actual products with decent size. In addition to the layout, you can also reload when you edit the logic, while keeping the state. In some cases, full reloading is required and the state will be cleared, but full reloading takes only about 2 seconds in our app.
It is very convenient to reload after making a small adjustment on the layout and the style. This helps to adjust the design, and building the UI little by little. Since it was hard to imagine the output from the Widgets tree in the beginning, I was repeating the reload quite frequently.
It depends on the application you are planning to build, but I think you can share 50–80% of the code for both iOS and Android using Dart.
In CARTUNE, the image editing function is implemented on the platform side (Android is Intent, iOS is Photos, and the license plate is detected in OpenCV). For other examples, SDK linkage such as Twitter is also implemented on the platform side by a plug-in mechanism. Other parts are shared between the Android / iOS version using Dart. Since quite a large portion of our code is related to image editing, about 70% of our code are in Dart and shared between the OSs.
I think the ability to write UI and the logic in a single code base, is a great advantage.
This depends on the individual skill and may not my view isn’t very helpful ….but I had an impression that if the cost of developing both OS separately is 100 (Android 35, iOS 65), Flutter costs around 30–50. (This is based on my personal impression based on my own experience).
Since Flutter is still under development, you can see some problems. There are more than 2,000 issues registered in GitHub at the time this article was written. I also personally encountered several bugs and sent Pull Requests.
Of course, since development is active, problems will be fixed and features will be improved, so you can expect this to get better as time goes.
Since it is still in beta, I think you will encounter some kind of a bug when your project grows to a certain size. In terms of stability, I think it is still a bit far from the level of platform native development (I haven’t compared with other cross platform SDK).
Lack of information is also an issue. Official site and documents are pretty rich, and the official sample application is also a good example. Even so, there are still parts that are missing.
In my case, when I was in trouble using Flutter, I read through the code inside Flutter. Flutter ‘s UI framework is also written in Dart, so it is pretty easy to read through. When I wasn’t sure about the Widget usage or had a question about specific behavior, I read the actual code within Flutter.
You can also expect a response from Googlers when you write the question on StackOverflow. I also read through the questions there. Flutter team also runs Google Groups and Gitter, but I haven’t been actively following it (because I do not follow much information on the system that flows).
Who sees the benefit and who doesn’t
Those Apps where UI building makes up a large proportion of the work, it will see the great benefit from Flutter. Those apps which requires a lot of device-oriented functions (for example, cameras) will see less.
It is not suitable to incorporate the framework into the existing application. Flutter allows you to transition to the platform native screen. However, it seems like it is better to use the Flutter screen as a core, and just use the platform native screens/functions as one off (taking the camera and take a picture and display a notice screen on WebView).
Also it is not for games (it’s not a game engine in the first place).
In the following cases, it seems to be suitable with Flutter.
- Iterating to fine-tune the behavior and appearance is easy with hot reloading.
- Since the concept of Widgets tree is similar to HTML DOM, it would be easier for designers to join the discussion.
Developing the new app from scratch
- You can apply Flutter from the beginning (Not recommended to use Flutter in small portion of existing app.)
- You can quickly start considering a workaround to avoid Flutter’s bug.
— Video was not supported at the time we built the feature (it exists now), we use the platform native screen and plays the video.
— The text form is a bit unstable when changing the line, we chose to use the platform native screen.
App which is about building up the UI
- Apps like News or Twitter like content.
Thanks to Flutter, our team was able to quickly develop applications supporting both Android and iOS. I am satisfied with the high development efficiency. Stability is still an issue, but the community is very active and I am expecting to see the improvement every day. (Of course I will also contribute too)