Ionic, React Native, and Flutter in One Nx Monorepo - Zero One Technology

Ionic, React Native, and Flutter in One Nx Monorepo

By Rohmad Sasmito, Senior Product Engineer at Zero One Group

One of the most common requests we, Zero One Technology (ZOT), get from our clients is to build cost-effective MVPs. We believe that building hybrid mobile apps fits the bill in terms of speed and cost.

Previously, our approach had been to use Ionic as our go-to mobile hybrid application solution. We have been developing an Ionic-based application for the last five months. As we added more and more features into the application, we found a number of challenges in building the application using Ionic. In particular, these include:

Considering the problems mentioned above, we spent some time looking into different hybrid-app solutions. We tried to build the same application with three different hybrid stacks. In this blog post, we will discuss a few alternatives along with their pros and cons.

Case Studies with Nx Monorepos

Nx has been a huge productivity boost in our development process to build products in a monorepo, and it comes with a lot of advantages. We can easily generate high-quality project skeletons that allow us to be productive immediately. We are happy to say that our experience has been overwhelmingly positive on Nx. For the comparisons to be meaningful for ZOT’s use case, we have embedded each hybrid stack in its own Nx monorepo.

Comparison Ionic, React Native, and Flutter

An illustration of an app and its available components

In this blog, we want to discuss how we build applications in different hybrid stacks in Ionic, React Native, and Flutter. We will discuss the advantages and disadvantages of each solution while assessing whether or not a framework is a good fit for the use case.

We decided to investigate the comparison of each solution based on a real use case. We have built this over a single monorepo, which you can see here. The final product is similar to the image shown in the banner above. We built it as simple as possible and our focus is to know more about the development experience of each stack.

Build Component

In the following sections, we will compare each solution by explaining how we build app components in each stack. The components we will discuss are AvatarTabsHeader, and Card. In Ionic and React Native, the components are called Components, whereas in Flutter they are called Widget as in the native term.


As shown in the image above, Avatar is a circular image with a border. Since it is Javascript in Ionic, we would only need about three lines of code. It is clear and simple.

An example of a code for Avatar in Ionic

Ionic uses Javascript, HTML, and CSS. We can add custom design to the above element by adding a few lines of CSS below We can also use rem in Ionic. However, In React Native, although it is Javascript, we cannot use rem for units.

An example of a code for Avatar in Ionic with CSS

In Flutter we can build Avatar using the block code below. Since we would have to use Dart to develop using Flutter, its syntax is the odd one out compared to JS-based stacks. We need to register assets folder into pubspec.yaml file.

These codes would be reasonably long compared to Ionic or React Native. However, Flutter has built Plugins for editors like VSCode as a remedy, which improves the development experience considerably.

Flutter Widget often uses a Container, similar to div in Web. Container has properties such as padding, margin, color, width, and height. Most flutter widgets use decoration property to customize the styles. In this case we used BoxDecoration as it provides a variety of ways to draw a box.

The child is an attribute to give a children box. Here, we use ClipRRect, a widget that clips its child using a rounded rectangle. Inside of ClipRRect we placed an Image to display an image.

An example of a code for Avatar in Flutter

Whereas in React Native, we can build an Avatar component using codes like below. Image is a built-in component in React Native to display an image. And inside of Image, we could place an image asset using require into a source attribute.

An example of code for Avatar in React Native

To add design, we could use a StyleSheet. StyleSheet is an abstraction similar to CSS StyleSheets.

As mentioned above, we are unable to use rem units in React Native. For the width and height, we use pixels or percentages instead.

An example of a code for Avatar in React Native with CSS


In the following sub-section, we describe the tabs in the example application, which is composed of a row of three buttons.

To make a Row in Ionic, we can use IonRow, a built-in component of Ionic. We can then transform each piece of button component into a Figure component.

Figure is our own component that receives parameter count and title both in string type. IonGrid is a powerful mobile-first flexbox system used for building custom layouts. IonRow are horizontal components of the grid system and contain varying numbers of columns. They ensure the columns are positioned properly.

An example of a code for Tabs in Ionic

However, when we want to build a component in Flutter, it would look slightly different. Dart and Flutter are type-safe, and Flutter Plugin will let us know whenever the types do not line up. Also, note the use of the const keyword, as we are not using declared variables.

Row in Flutter is a widget that displays its children in a horizontal array.

An example of a code for Tabs in Flutter

In React Native, It looks pretty similar to Ionic. It is fairly simple even though React Native requires the use of built-in components. The difference to Ionic is we cannot use div. Instead, we use View, which is a container that supports layout with flexbox, style, some touch handling, and accessibility controls.

Though it looks like an Ionic component, inside of View we put children that are called Figure component. The difference is only the background parameter, since we cannot use :nth-child in React Native like in Ionic.

An example of a code for Tabs in React Native


Header is a light-colored box with a title on the left and a small action button on the right side. In Ionic, it has the codes shown in the image below. There is an IonRow on the outside, and on the children’s property, it has IonCol. Inside it, there is a div with a tag paragraph and IonIcon to display an icon.

An example of a code for Header in Ionic

As mentioned above, we use a Container in Flutter as we need to give color, and padding. On the children property, we place a Row to display the title and an action button, which will be laid out horizontally. GestureDetector is a widget to detect gestures to make the icon clickable.

An example of a code for Header in Flutter

In React Native, to build a header with a title and action in horizontal view, we would use View, and place a couple of Text and Icon like in the image shown below.

We do not use any libraries to handle icons. Instead we are only importing an svg. because it was not as straightforward to add an icon library. Therefore, we prefer to only import svg, just like what we did when building a React application.

An example of a code for Header in React Native


Card is a box that contains post articles such as avatar, date, username, title, comments, likes, and share button.

In Ionic (code), there is an IonLabel, which is a wrapper element that can be used in combination with other built-in components such as ion-itemion-input, and ion-toggle. The position of the label inside of an item can be inlined, fixed, stacked, or floating.

For Flutter (code), the codebase may look similar to the Ionic counterpart. You may also notice we are using an Expanded widget. Expanded is a widget that expands a child of a Row, Column, or Flex so that the child fills the available space. Using Row, we split the box into 2 parts in our Flutter codebase. On the left side we placed an Avatar Image with defined size, and on the right side we placed date, username, description, comments, likes, and share button. We also used Expanded to fill up the remaining space on the right side of the box.

As for React Native (code), there is nothing new in the codebase. We simply use View, Text, SVG Icon, and other components we have mentioned before.

Comparison of app in Ionic, Flutter and React Native


We have explored how to build the same application in three hybrid stacks. The initial setup of developing them was fairly straightforward. However, the hardest part is keeping it simple when we add more and more features to the app, especially when the UI becomes complex. For our use case, it is important not to be confronted with a stack-specific development blocker. For that reason, we very much value the ability to easily find solutions on Stack Overflow and a responsive community on the project’s repository.


When we look at the Ionic official repository, we see a lot of open, long-unanswered issues. This indicates that the Ionic community at Github is less responsive. Although we often find answers on Stack Overflow, they are often framework specific.


When we look at the official Flutter forum, we see that many issues are still open like Ionic. However, upon further inspection, it looks like the community is active enough to respond to each issue. Furthermore, this technology is made by Google, which has a big supportive community and staff dedicated to maintaining their open source projects. So if we were to build a mobile application with Flutter, support would be quite low in our list of worries.

React Native

When we look at the official React Native forum. We see that the community activity is comparable to that of Flutter. And since React Native was built by Facebook, we also would not need to worry much about community support.

Final Thoughts

The hybrid-app solutions, Ionic, React Native, and Flutter have been growing fast in popularity. These technologies provide us with fast development at a relatively low cost. These solutions also give us the ability to create beautiful, high-performance apps that work everywhere.

Ionic’s guiding principle is to use the web platform and embrace open standards wherever possible. When we build an app with Ionic, we will learn and apply the tools and languages of the web, using a framework designed to deliver great performance on mobile, desktop, and especially, the web.

Flutter, in contrast, has chosen to go at it alone, creating a self-contained ecosystem that is at odds with the common languages, toolsets, and standards found in the broader hybrid app development world. Thus, if we choose Flutter, we will be learning the Flutter way of doing things. Of course, there are clear benefits to a custom architecture that has one single purpose, as we’ve seen in some of their impressive early demos.

Ionic is very popular as it eliminates the learning of a new language factor whereas Flutter needs the developers to learn Dart programming language in order to build cross-platform apps. Although, when it comes to building highly graphical apps, Ionic is never the first choice of the app developers; React Native comes into play in this case. Flutter is new compared to Ionic and React Native but is soon getting the recognition it deserves.

Consideration Upon Choosing a Framework

Choosing the right framework for a company like ZOT can be challenging. However, to simplify the initial stages of building a mobile application, we try to come up with a rule of thumb for choosing a framework depending on the situation.

We would suggest using Ionic, when:

Flutter when the business:

We would try to avoid React Native for the following reasons;


Follow Zero One Group at InstagramTwitterFacebook, and LinkedIn. Visit our website at


Discover the significance of cross browser compatibility and how to perform free cross browser testing. Dive into its evolution and learn why it matters for universal user experience, accessibility, reputation, SEO, cost savings, conversions, and future-proofing. Explore when and what to test, plus a guide to effective testing tools. With our comprehensive insights, master the art of creating websites that work flawlessly across browsers for a credible and successful online presence.



Jl. Martimbang VI No 8EF,
Jakarta Selatan 12120
Part of
Copyright © 2023 ALL RIGHTS RESERVED