Impressions From A Flutter 101 Talk Coming From React Native

Alex Finnarn
The Startup
Published in
12 min readOct 25, 2019
Flutter homepage image

Recently, I became frustrated enough with an Android exercise app that I decided to build a “better version” of that app myself. I say “better version” because my exercise app still has a ways to go before it is stable enough for me to call it a better version.

One huge problem at the start of my journey was lack of knowledge on how to build an Android app including not knowing Kotlin or Java and not using Android Studio or the Google Play Console ever before. After briefly trying some statically-typed compiled Kotlin, I lusted for my dynamically-typed scripted developer experience. Debugging is just so much better when you can follow the code around at run-time rather than trying to decipher weird compile-time errors.

Luckily for me, React Native made the experience of developing my app a joy. I already knew JavaScript and React, and I could put my knowledge to use immediately while still using state management tools like react-redux as I had on web-based projects. I even liked the Flexbox-based layout engine, Yoga, after years of hating trial and error CSS work. It all just made sense to me.

But You Gotta Try Out Flutter

Then I kept seeing mention of Flutter. You could say that Flutter and React Native compete for the same type of development projects even though they have different focus areas and strengths and weaknesses.

To me, React Native aims to bridge the gap for developers who already know JavaScript and React but have little knowledge of developing mobile applications. These developers probably aren’t going to build a mobile app unless React Native existed; however, React Native is also a great “gateway drug” for them to hop into native Android or iOS development.

I like the bridge as a metaphor and in practice, since you’re not only talking about building a slick UI but also providing JS developers the power to interact with all native APIs potentially without needing to know any Swift or Kotlin at all. On top of that, it’s not all that hard to understand what’s going on in Kotlin or Swift if you want to file an issue or fix a bug you find while working with a React Native module.

StackOverflow Trends for ‘react-native’ vs. ‘flutter’

It wasn’t until I saw a trend overview for “Flutter vs. React Native” that I started to pay more attention. Flutter looked like it was skyrocketing to the top of the cross-platform app builder projects, but it is always hard to find the time to do a good comparison and see if another platform warrants more of your attention. Luckily for me, again, I got to sit in on a “Flutter 101” talk at a local Google Developer’s Group meetup and came away with a lot better impression of the Flutter project and how to best use it.

Flutter 101: Origins And Purpose

First of all, I’d like to thank Scott Stoll of the Flutter Community for giving the presentation at GDG Columbus. Scott comes in with a lot of experience in the Flutter community and with Google related tech in general. Scott started at the beginning of it all…

“It was unveiled at the 2015 Dart developer summit, with the stated intent of being able to render consistently at 120 frames per second.”

That quote is actually from Wikipedia, but Scott told us of a similar tale. He mentioned that Flutter was intended to be a toolkit for building fast UIs rendered on a canvas using OpenGL. It took me a bit to find more details on Flutter and OpenGL, but I now see that Flutter uses OpenGL internally, but they didn’t expose any bindings that developers can use.

“Internally Flutter uses OpenGL to draw, but we don’t currently expose OpenGL to authors. Instead, we expose a 2D drawing API via the Canvas interface”

120 fps + a 2D drawing API brings up a good point about what Flutter is and isn’t. Scott lamented that some people give Flutter shit for not integrating with native APIs, but the Flutter project never had any intention of doing anything with native platforms.

Flutter simply wants to make it easy for you to have a native-like UI experience cross-platform while only having to maintain one codebase. Most of the time when someone asks “Is that native?” they look for something like jittery animations or a delay in response from user input to tell if you built the app in React Native or Kotlin/Swift. Supposedly Flutter makes it really hard to tell vs. a tool like React Native since no abstractions or bridges are used.

As an aside…the React Native team has been hard at work on a re-architecture that will streamline how the React code interacts with native modules and improve performance. The improved codebase should come out at any time now.

Platform Channels

So how do you talk to native APIs then? In my exercise app, I needed to run a timer in the background when the user has the screen turned off as well as trigger text-to-speech when the timer reached certain points. None of that involves a 120fps UI.

Platform Channel Diagram from https://flutter.dev/docs/development/platform-integration/platform-channels

Flutter has the concept of Platform Channels. It’s a pretty simple concept really. The main Flutter app sends asynchronous messages to the host platform and waits for a response to come back that updates the UI. You still have to write iOS or Android code on the other hand, but the Flutter side of the equation is pretty straight forward.

static const platform = 
const MethodChannel('samples.flutter.dev/battery');
// Get battery level.
String _batteryLevel = 'Unknown battery level.';
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level at $result % .';

Some Android, iOS, or whatever platform code goes and finds out what the battery level is and passes it back to Flutter as an integer. The docs for Platform Channels provide code samples you can review on getting the actual battery level of a device, but passing that data onto the UI is straight forward. I also saw the mention of isolates in relation to passing messages around, but I’ll let you do the homework on what that means exactly.

React Native Architecture Diagram from https://formidable.com/blog/2019/lean-core-part-4/

When you look at the new React Native architecture, “Turbo Modules” effectively act as the Platform Channels communicating to the UI manager, “Fiber”. Just to show a similar example in React Native, let’s write some pseudo-code…I just did a quick Google and of course, several npm packages pop up with similar APIs and download metrics.

import BatteryChecker from 'react-native-battery-thing';

let batteryLevel = 'Unknown battery level';
const result = await BatteryChecker.getBatteryLevel();
batteryLevel = `Battery level at ${result} % .`;

Same thing. A message is passed off to the platform and once data comes back the message gets rendered to the UI. It’s kind of crazy how similar the JS code snippet looks to the Dart code. The main difference being how the MethodChannel is used in Dart/Flutter whereas we don’t know how the BatteryChecker is passing messages back and forth.

Dart As A Language

Now that we’ve seen a little bit of Dart code, I can tell you all about how little I know of it. Fortunately, Scot knows a good bit about Dart and he describes it in relation to C#.

“Dart is like C# but drop the public/private for methods in lieu of underscores and use leading lower camelcase.” — Scott Stoll

Essentially, he is saying that if you know C#, you’ll feel right at home with Dart. Hell, I don’t know a lick of C# but so many languages have cross-pollinated their syntaxes that Dart even looks familiar to me. I think it probably wouldn’t take me too long to pick up Dart if I become more interested in Flutter.

Dart also looks a bit like JavaScript and runs on a single thread as well. Some people say Dart is Google’s ideal version of JS or something like that, but Dart and JS are pretty closely tied together. Enough so that the same body that sets the standards for JS also sets the standards for Dart. This association makes it easier for Dart to stay in sync with and transpile down to JS.

My big issue with learning Dart is that I don’t have to. When I look at job postings, in general, I rarely ever see Dart or Flutter mentioned but I do see C#, Java, Kotlin, Swift, JS, Python, Ruby, Go, etc…and I only have a decent command of some of those languages. Yes, learning Dart is probably not hard, but why start learning it if you don’t even know a lot of the most popular languages?

I’ll go so far as to give you this piece of advice: If you’re immediately looking for a job and need to obtain work now, I’d spend your time learning a language or framework you don’t know well that you see in many job postings (maybe React Native) and/or studying computer science fundamentals. However, if you don’t need to secure money and a roof over your head now, then learning Dart and Flutter might be the way to go. Some people say that “Flutter is the future of mobile development,” and there are still many gaps you can help fill and truly become part of a community.

Garbage Collector

Scott took some time during his presentation to go over the garbage collector. Coming from a PHP and JS background I didn’t know what the hell he was talking about as I always let the garbage collector do its thing. I can count on my hands the number of times I used unset($variable) or delete theVariable in my work. I know, you probably wouldn’t hire me onto your dev team, but I think it’s safe to assume that not many developers who use scripting languages think about garbage collection and memory leaks.

There is an article called “Don’t Fear The Garbage Collector” that goes over how garbage collection works in a Flutter app. Some say that the collector is neat and how it can achieve clearing 10,000 objects in one frame and/or keep an app running at 120fps on an iPhone 6. Others aren’t convinced and think that the GC and how it functions is pretty standard.

Hot Reloading

Hot Reloading is one feature people are convinced about and think is super neat. To me, it looks like most of the people who think hot reloading is amazing come from developing Android apps and not from using JS and Node.

I’ve been accustomed to hot reloading for years when building a web app. npm run dev usually connects to a command that will watch your code for file changes, lint the code when you save a file, and then reload your browser with the new code for you. The state is usually preserved as well.

When I briefly tried Android development, I became dismayed with waiting for Gradle builds to finish after I made a code change. For my small app, I think the reload time was something like 10 seconds, but for larger apps, I’ve heard horror stories of 10+ minute build times. Android Studio does have a preview for design-related changes, but it's much nicer to view code changes in an emulator or on a device.

A Flutter app uses Ahead-of-time (AOT) compilation, but I don’t know enough about the topic to tell you how that fits into hot reloading or how hard or easy it was for the Flutter team to add this feature. I think AOT compilation is for production releases while in development mode a VM runtime allows for files to be injected and hot reloading to work.

I can tell you that it looks like you have to do extra work in order to get hot reloading to work in tandem with file watching. The docs mention hitting r when you’re in the command line or using “Flutter’s IDE tools”. Your app should reload pretty quickly and also preserve the state of the app once reloaded. I guess installing the IDE tools would get me to the same “save, see reload” workflow I’m accustomed to so I probably wouldn’t have any complaints with the process.

It is important to note that hot reloading can fall down when you need to change larger sections of code or update dependencies of your code. There is a concept of a “hot restart” too that will throw away the state.

“For example, if you modify a class definition from extending StatelessWidget to StatefulWidget (or the reverse), after hot reload the previous state of your app is preserved. However, the state might not be compatible with the new changes.”

I certainly don’t have the best picture of what all the differences between hot reloading, hot restarting, and just plain ‘ole restarting are, but there is a GitHub issue you should bump if you want the docs to have a distinct section on the matter.

Writing Widgets

In Flutter, everything is a Widget…well, that’s not true, but you will mostly be developing in Widgets. Underneath Widgets lie Elements, which are concrete representations of the configuration declared in Widgets. To render the Element, a RenderObject takes over and draws the Element to the screen. There’s plenty of more detailed information on the Widget -> Element -> RenderObject flow, but for starters, you only need to worry about Widgets.

Widget build(BuildContext context) {
return MaterialApp(
title: 'Hello World App',
home: Scaffold(
appBar: AppBar(
title: Text('Hello World App'),
),
body: Center(
child: Text('Hello World'),
),
),
);
}

That code sample is the Flutter version of the popular “Hello World” program. As you can see, the Widget is a collection of constructor functions describing everything from printing text to a screen to layout to routing to a base app container.

If you’ve written code using the React framework, then this should all look familiar. I came into React after Hooks came to be, and I’ve always been writing components as functions. Flutter apps boil down to a set of functions accepting other functions as parameters, a.k.a higher-order functions. Writing applications in this fashion allows for the same reactive, declarative UI in Flutter that you see in React without the JSX.

var container = Container(
child: Text(
"Lorem ipsum",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.w900,
fontFamily: "Georgia",
)
,
),
...

Styling a Flutter app also looks a lot like how you would do it in React Native or React and styled-components. TextStyle is a Widget that applies styling to certain other Widgets. Just like on the web, the canvas starts drawing on the screen from the top left corner unless you provide positioning style attributes. From a quick peek, it looks like a lot of CSS knowledge will transfer to styling a Flutter app. I was intrigued to see a Center() widget that supposedly centers other widgets vertically and horizontally as I’ve had trouble doing that occasionally when using React Native.

Potential spaghetti code is one complaint I saw relating to writing Widget code from the perspective of a new Flutter developer. This developer felt that you could easily combine UI code and business logic in one file just like you can with PHP. Yes, unfortunately once again I see the language I’m most familiar with mentioned in context to practices that no “professional” PHP developer would use, but it is a valid point.

Just like in some React code I’ve written, components can get quite heavy when you try to make them do too much, but that’s a good opportunity to refactor your app by breaking that component into smaller parts. In Flutter, composition is favored over inheritance, and I think making that mental switch is hard for developers who are used to always extending some class to get their work done.

Final Thoughts

My view on exploring Flutter is nuanced based on my immediate job hunting skill needs. I simply don’t have the time to really dive in and explore building an app in Flutter right now since I have a hard enough time convincing people of my JS prowess. However, I don’t want to stop your investigations.

I also tried Googling “background timer” for both React Native and Flutter. Adding a background timer requires running code in the background and can get hairy with you potentially having to dive into native code if the community solution hasn’t been developed yet. The React Native search results had more ready-to-install community packages whereas the Flutter search results had more explanations of how to write the code for a background timer. Even though many React Native community packages have bugs and are semi-abandoned, you will find more projects you can npm install than with Flutter. I’m sure this metric will change over time as Flutter gets more popular.

To get more information on Flutter, the best place to go is a Google group. Scott told us that core Flutter devs routinely respond to posts on that forum so it’s a good place to hang out and lurk in. One of the biggest needs of the Flutter community is documentation so a good way of contributing might be to find well-discussed forum topics and make sure that those discussions and answers to issues are documented on the main Flutter docs site.

Whether you use Flutter, React Native, NativeScript, Xamarin, or some other cross-platform solution, I think now is a great time to start exploring what I call “universal UI” projects that aim to abstract building the UI from the target rendering platform. I see these universal UIs as the way forward for web development as well as mobile, desktop, and whatever the internet of things dreams up when we’re all living in the Matrix.

--

--

Alex Finnarn
The Startup

Thorough opinions + meandering Scots-Irish wit = readable dev banter. Redoing my blog at: https://alexfinnarn.github.io.