We Rebuilt a React Native App with Flutter

And we are very excited about it!

Last year, we launched a React Native starter kit called Flat App. This kit contains a flat UI design along with Redux and NativeBase components for iOS and Android application.

Flat App is basically a style of interface design that emphasises on minimal use of stylistic elements. Developers are known to prefer a flat design as it allows interface designs to be more streamlined and efficient.

Flutter Flat App

As an experiment, we were able to successfully rebuilt this app using Google’s Flutter. The result was truly amazing.

In this post I will talk about Google’s Flutter by comparing it’s Language Stack, UI, Style and other things with that of React Native. Simultaneously, I will also go into some of the challenges that we faced while rebuilding the Flat App, and the tricks that we used to overcome them.


TL;DR


Dipping Our Toes Into Flutter

Back in July 2017, Sanket Sahu and Atul Ranjan had the chance to chat with Seth Ladd and Yegor Jbanov from Google’s Flutter Team.

Flutter is a platform built by Google that allows us to create extremely fast apps that can run on both Android and iOS platforms.

During this conversation, we spoke about Flutter’s operation, how it is being developed, and it’s future.

Our talks with the Flutter Team continued even after we got back to India. We regularly speak with them about our experiments with Flutter.

What makes Flutter different is that it has a thin layer of C/C++ code but most of its systems are implemented in Dart that developers can easily approach read, replace, or remove. This gives developers tremendous control over the system.


The Language Stack

While React Native is a JavaScript library, Flutter is a SDK that works on a completely different programming language called Dart.

JavaScript

Though JavaScript was initially created only for web development, today, this language with it’s numerous additional libraries has grown so huge that there are maybe a handful of areas that are without it’s presence.

React Native compiles its dynamic JavaScript code to native view at runtime. The rest of the code runs in the additional virtual machine that is packaged inside the app itself.

Dart

Dart is a general-purpose programming language that was developed by Google. It can be used to build web, server and mobile apps and for IoT devices as well.

Dart is influenced by many different languages. The strongest among these influences would be of Java. A Java programmer can easily notice similarities between these two languages.

Dart is an object-oriented programming language and supports things like abstraction, encapsulation, inheritance and polymorphism.

Dart programs can run in one of these two modes:

  • In checked mode, dynamic type assertions are enabled. These type assertions can turn on if static types are provided in the code. Checked mode is recommended for development and testing as it is helpful in catching errors in your code when types do not match.
  • Production mode is the default mode of all Dart programs. It provides a faster way to run your program.

Example of Dart:

Although Dart has a strong community presence, it is still overshadowed by other mainstream languages like JavaScript and hence very few developers even know about Dart.

But this changing at a very rapid pace. All thanks to Flutter’s Beta 1 launch! Already, Flutter’s GitHub Repo has gained 18K stars at the time that I was writing this post!

Flutter has a functional-reactive framework that is inspired by React. Though Flutter is written in Dart, it also takes the best features of React and helps the developers build a beautiful, cross-platform mobile app.

React Native
Flutter

Style

React Native

In React Native, styles are defined using JavaScript. All of React Native’s core components accept a prop named style. Style names and values are usually similar to those of CSS on web. The only difference is that in React Native, the names are written using camel casing. So to define the background color, we will name our style as backgroundColor instead of background-color.

Our code will be cleaner if we use StyleSheet.create in order to define multiple styles in one place. This will be extremely helpful as our app grows in complexity.

Flutter

Difference in styling is more obvious in Flutter than in React Native. This will be evident from the example given below.

Here is a React Native code that defines font style and other text attributes that are handled by CSS.

The same code, if we want to implement in Flutter will look like this:


Architecture

React Native

React Native’s application architecture is known as Flux. Facebook uses Flux to build client-side web applications. Flux utilizes a unidirectional data flow. Flux is rather more like a pattern than a formal framework. Anyone can start using Flux immediately, without the need to write lot of new code.

The unidirectional data flow is the main concept of Flux.

The Dispatcher, Store and View are independent nodes with distinct inputs and outputs. The Actions are simple objects containing the new data and a type property. The View might cause a new action to propagate through the system in response to user interactions.

Flutter

Flutter has a Dart app architecture library called Flutter Flux. It is a unidirectional data flow inspired by RefluxJS and Facebook’s Flux.

Flutter Flux does not have official support from Flutter team and is an experimental package.

Flutter Flux is almost the same as the one implemented in React/React Native. It is modified to use Flutter instead of React.

Flutter Flux’s implements a unidirectional data flow pattern that consists of Actions, Stores, and StoreWatchers.

Actions the modification of app data that resides in Stores. The data modifications within the Stores trigger the re-rendering of the App’s View.

Flutter Widgets and other interaction sources dispatch Actions in response to the user’s input.


User Interface

React Native

Using React Native is similar to using HTML without any CSS framework.

Unlike Flutter’s Flat App, in React Native we had to use third-party libraries since React Native does not have a UI components library of its own.

We used components such as NativeBase, which is an open-source UI components library created by us. React Native Elements, React Native Material Design and Shoutem are other similar UI libraries that are available to the user.

Flutter

Flutter has its own UI components, along with an engine to render them on Android as well as iOS platform. Most of these components conform to the guidelines of Material Design.

We are using Flutter’s in-built components for the UI development of our app. These components are called widgets. Here, we only had to use the right widgets and pass the right props to the widgets to get the desired UI for our screens.

Every widget in the Flutter is defined by their own properties and can be nested inside other components. Widgets can also call upon the properties of its parent component.

Flat App in Flutter performs better than the one in React Native because it has minimal interaction with the native code. This is also why animation in Flutter’s Flat App are faster.

In React Native, we can bridge native modules as well as use native UI components. But this is not possible in Flutter since Flutter has its own rendering engine.

This is actually why Flutter has not been able to support Google Maps yet.

Here are a few examples of Flutter Widgets:

  • Drawer

Drawer is a Material design panel that slides in horizontally from the edge of a Scaffold to show navigation links in an application. Here’s the Drawer from the Flutter Flat App alongwith its React Native equivalent called SideBar:

React Native Flat App’s SideBar Component
Flutter FlatApp’s Drawer Widget
  • Inkwell

Inkwell defines a rectangular area of a Material that responds to touch. We have used this widget to create a ripple effect when the user touches the screen.

In React Native, we don’t need to create a whole new component to create this ripple effect. React Native’s TouchableOpacity already has this effect as default.

  • GestureDetector

GestureDetector as the name suggests, is a widget that detects gestures. GestureDetector attempts to recognize gestures that correspond to it’s non-null callbacks.

If this widget has a child, it defers to that child for its sizing behavior. If it does not have a child, it grows to fit the parent instead.

As shown in code below, the GestureDetector widget will defer to the Container widget for its sizing behavior.

GestureDetector is the equivalent of TouchableOpacity in React Native. So, we do not need to create any new components here.

  • DefaultTabController

DefaultTabController is the default TabController widget and is used for widgets that don’t specify one explicitly.

It is an inherited widget that is used to share a TabController with a TabBar or TabBarView. We have used this widget to share the TabController with a TabBar.

This widget is used when sharing an explicitly created TabController isn’t convenient as the TabBar widgets are created by a stateless parent widget or by different parent widgets.

In the React Native Flat App, we used the Tab Navigator to perform the same operation.

Tab Navigator in React Native
Flutter equivalent of Tab Navigator

Plugins

React Native

There are loads of contributions available for React Native as it is backed by a huge community.

This also why React Native has more third party libraries/plugins than Flutter.

In our React Native Flat App, we used many different third party libraries, such as Calendar, Carousel, and Modal. [I had added GIFs for these, but they didn’t that good. Working on it]

Flutter

We integrated our Flutter Flat App with Firebase to provide login and signup functionality.

In Flutter, we need to add separate files for both iOS and Android platform. In each of these files we need to add code that corresponds to the rules of the platform.

Using Firebase with the Flutter app is quite difficult. Check out this codelab by Google how to add Firebase to your Flutter app.

It is also quite easy to build new plugins for Flutter that are more suited to the developer’s needs. You can see a new plugin for Flutter almost every other day.


Community

React Native

React Native was created by engineers at Facebook and Instagram in 2015. Since then around a dozen of their engineers have been working on React Native full-time, always trying to make it better and help users clear any issues that they are facing.

But there are also far more people in the community who make key contributions and fix things. If you need help with your React Native app, the right place to go depends on the type of help that you need.

You can usually find the solution to most of your questions in React Native documentations and guides. Or you can connect with other React Native developers at StackOverflow and GitHub where you can either show-off your work or ask other developers for guidance.

If you want to contribute, start by reading the contributor’s guide and then take a look at the Roadmap to learn more about what other people are working on. You can also check out this list of most popular features that is requested by the community.

Flutter

Flutter’s documentation is thorough enough to help you get started with app development using Flutter.

Flutter Gallery showcases all the Flutter components that are available to us. We can also refer Flutter’s GitHub repository for their implements.

Flutter’s community is not as strong as the one for React Native. But support provided by the Flutter Team at Google is really good. They provide many ways to post our problems and they address the questions posted within a reasonable time frame.


Issues

React Native

Though React Native has a single codebase (JavaScript), it’s View component behaves differently on iOS than it does on Android.

Though React Native’s massive community support provides us with many different plugins/libraries, this can also result in conflict with other plugins of existing projects.

Flutter

If you are coming from a JSX environment, writing Flutter’s UI code might seem a bit tedious to you. Code readability also goes down as your UI gets more complex and nested.

One solution for this is to refactor your code into methods and widgets. We are currently trying this out to see if it makes the build() methods easier to read.

It not necessary in Flutter to keep your code inside a giant nested build() methods. Instead you can break it out into smaller widgets!

When compared to React Native, Flutter’s resources do seem to be a bit lacking. A big reason for this is that Flutter has not been around for as long as React Native has. But since it’s Beta release, there has a been a huge growth in Flutter’s resources.


Wrap-Up

From our work on Flutter, we were able to see exactly why a developer should consider using it to build their apps.

One main benefit of Flutter is that it has in-built UI components. So unlike in React Native, we don’t need to import third-party UI libraries.

By reducing the interactions between the Native Layer and Runtime Environment, Flutter enables the app to run more smoothly and quickly than React Native apps.

Flutter has just entered the Beta phase of its development. But there are already quite a few developers out there that are using it to build their apps. The official app of Hamilton is one such app.

Flutter still has a long way to go. Google’s Flutter Team is working full-time to bring Flutter to the masses.

With the recent release of Flutter’s first beta, we think that day will be here soon!


I am Rajat S, a Technical Content Writer at GeekyAnts. Aspiring Coder who has a long way to go. A Die-Hard DC Comics Fan who loves Marvel Movies. 😛 Follow me on Twitter to know about all the amazing things that are happening at GeekyAnts.

Flutter Flat App is built by Rishab Jain, who is a software developer at GeekyAnts.