As an Android developer, I never really liked cross-platform solutions. I thought they would never be able to match the smooth animations and responsiveness of native apps. After looking at some of the new and updated frameworks, I realized this was no longer true. The difference between them had become minimal. I wanted to make a replica of the first Android game I made. It was a simple 2D game with a 3x4 grid view filled with squares where one randomly selected square wouldn’t be the same color as all the others.

So I tried React Native as it had great support and a lot of outside contributors. After a few days of going through no real IDE support, choosing from many versions of even the simplest libraries, reading the really poor documentation and not really making much progress, I started to look for alternatives. I was already determined to make the iOS app without using Swift or Objective-C. There had to be a better way than this. One of the alternatives was Flutter — I remembered hearing about it and I wanted to give it a try.

Game screen

Trying Flutter

Flutter is a reactive SDK for building cross-platform apps that instead of using OEM widgets provided by the platform actually draws them by itself. That’s all I knew about it. Before that, I had never seen any Dart or Flutter code. To start off, I played with their gallery_example app to make sense of what was I getting myself into. After React Native I was prepared for the worst, but Dart actually turned out to be so intuitive that it took me only a few hours to make the first game prototype in Flutter. Exceptions are shown within the widget that caused it while the rest of the app still runs just fine, instead of slapping you with the red screen with no actual information about the exception like in React Native.

The great thing about it is that everything is written in Dart and most of it is documented pretty well on their site. Even things that are not documented or that are missing are easy to figure out as you can just jump into the code and see what exactly is happening in that built-in widget since they are just the same as any of your custom widgets.

After I made a working game, I wanted to add more functionality to it. At the time it was just a screen with a grid view, there was no main menu or anything else really. After adding the main menu and the game over screen, I wanted to add animations and make it feel smoother during game-play. It was surprisingly easy to make complex animations, control them and chain multiple animations!

Now that the game looked great, I added Google login and a real-time database to keep track of high scores and show them within the game. There are Firebase plugins that are easy to use and simple to set up. Since all of that was already built or built by the Flutter team I wanted to see what would it take to implement some functionality that is not widely available as a finished library or native component, I decided it would be a good idea to sync random generator from the game with NTP service. That way when I was animating color changing in the main menu all ‘random’ colors and animations would sync up on all other devices, and it could work offline as long as the local clock on the device didn’t drift too much. Implementing this was more challenging but completely doable.

While I found a bug in Flutter when receiving data from RawDatagramSocket that I used for communicating with NTP service, the bug was fixed fairly quickly given that it was not crucial feature or part of a big production app.

So I should use it?

Unfortunately, since it is in alpha, it means some things are just not ready yet. There are no maps or in-app browser widgets. Even though you can use a library for that, which will launch maps or web browser in a new native activity and communicate with the Flutter app, there is lack of flexibility or customization that I have got used to with Flutter. While this is a setback, it can be solved by making a clone of the ‘url_launcher’ library from Flutter team, customizing some of the parameters and the layout of the browser view that was displayed, so everything still looks like a part of the app.

Although this seemed like a big problem, it was actually fairly easy to make native activity and communicate with flutter app over PlatformChannels. While this seems to be just a minor detail, the reality is that most of our clients want to show maps somewhere in their apps and that sometimes makes it impossible to even try and use Flutter for development. They are working on it (Issue #73), but as of the time of writing this article, there is no support for that.

So I shouldn’t use it?

Flutter is a good solution for simple cross-platform apps at the moment, but once Flutter gets released, it could really disrupt mobile development just by the fact that it really decreases development time. Dart makes it really easy to transition from Java, Kotlin or even JavaScript. It’s really easy to understand and you can actually ‘read’ the widgets without the need for a visual editor. This is important today as every app has its own customized widgets allowing for full app customization and Flutter’s rendering engine makes it possible to have 120 fps animations. Unfortunately, the only thing getting in the way of using Flutter much more is the lack of support for maps.