Mobile Development with React: Native or Ionic
Andrew Moscardino | September 7th, 2021
React is one of the most popular JavaScript frameworks for building interactive UIs on the web. We use it at AWH because of its speed, simplicity, and mature ecosystem. The component-driven model is powerful and easy for developers to pick up. We love developing web apps with React, but how can we apply those skills to mobile app development?
It turns out there are several ways, but I want to look at two: React Native and Ionic Framework.
How to Build a Cross Platform App
Before we dive into the details on each framework, let’s take a step back and look at the two main approaches that are used to build cross-platform mobile apps.
The first is what I consider the hybrid approach and is what Ionic uses. The idea behind this approach is to wrap your app’s code in a lightweight shell and draw the UI in some sort of canvas. For Ionic, this shell is called Capacitor and is basically a super-powered browser that looks and behaves like a standalone app. Your code is written in HTML, CSS, and JavaScript, and rendered by a browser.
Flutter and others also use a similar approach where the framework renders each control to the screen using a low-level graphics library and a canvas control instead of a browser.
The other main approach is what I like to call the “native” approach. This is what React Native and Xamarin.Forms (soon to be .NET MAUI) use. The idea here is to take a single code base and write your UI in a way that the framework can convert it into platform-native controls. In Xamarin.Forms you use XAML, and in React Native you use JSX. For instance, when you want to render a button, the framework will render a UIButton on iOS and an android.view.button on Android.
Each approach has its benefits and trade-offs. By examining React Native and Ionic (which both use the same core React library), we can see how each approach differs and where they are the same.
To aid in this comparison, I’ve created a simple app using both frameworks. The source code for both is available on GitHub. View the React Native app here and the Ionic Framework app here.
React Native
React Native is a mobile app UI framework created by Facebook in 2015. It sits on top of the core React library and does not replace it. Instead, if you are familiar with React in the browser, it replaces React DOM. Where React DOM renders HTML elements, React Native renders platform-native elements.
You still write components using JavaScript and JSX, but it’s not a browser that runs your code. Instead, React Native uses a background process that interprets and executes your JavaScript and renders native UI controls. Despite still using JSX, you don’t write components that render HTML. Instead, you use a set of native components provided by React Native that correspond to some basic UI elements on the platform. React Native’s documentation has a comprehensive list of all these components, and they are very basic. Things like View, Button, FlatList, etc.
Those native components are basic because they are meant to be used as the smallest building blocks that get composed into larger, more complex components. Styling these native components is done using JavaScript objects and a StyleSheet API. These styles work a lot like CSS, but are decidedly not CSS, which can make the transition from web development a little tricky.
Aside from the core native components, React Native does not include much else. It’s a very basic framework, which relies on you to either find a library or write your own to implement functionality. It’s a “batteries-not-included” approach. This is where Expo comes in. Expo is a collection of tools and APIs that make React Native more complete and easier to use. The CLI is useful for bootstrapping, building, testing, and deploying apps. The SDK also includes lots of APIs for interacting with native functionality using only JavaScript; things like the Camera, Gyroscope, Network status, and many more.
Expo also provides some optional cloud-hosted options for testing and distribution.
Once you pair React Native with Expo, it becomes a more complete picture. Add some libraries to fill in common functionality, then you can really piece an app together pretty quickly. For the sample app noted above, I used a library called React Native Elements to provide some basic styles and React Navigation to provide some basic navigation functionality.
Ionic Framework
Ionic Framework is another mobile app UI framework that has been around since 2013. Originally it was built on top of AngularJS and Cordova, but recent releases are now framework-agnostic and use a new wrapper called Capacitor. Ionic apps are web apps written in HTML, JavaScript, and CSS. Ionic is like Expo in that it contains a CLI to aid with bootstrapping new projects, running, debugging, testing, and deploying. It’s also a UI library that provides a set of pre-built web components to mimic native platform controls.
Because Ionic is comprised of web components, it supports multiple popular front-end frameworks. Current support includes Angular, Vue, and React. It’s also possible to skip the framework entirely and use only plain JavaScript. Since the components are built using standard web technologies, they are easy to customize and style using CSS like any other web app.
Some Shadow DOM usage can make styling some components trickier than others, but their documentation does a good job explaining how to work around that and flagging components where that may be a problem.
For many web developers, the word “Cordova” makes them run away with bad memories of clunky web apps badly wrapped as native apps. Cordova is still supported by Ionic, but it has been effectively replaced with Capacitor. Capacitor acts as a super-powered web view: a browser that looks and acts like a native app. But it’s not a browser, as it has the ability to interface with platform-native code. There are a handful of official plugins to interact with native APIs, as well as many more community plugins. Legacy Cordova plugins are also supported and work perfectly well. This interoperability means it’s easy to add a plugin to your app to allow the app to interact with platform features like the Camera, Gyroscope, Network status, and many more, all in JavaScript.
Ionic is a very complete framework. In addition to the suite of UI components and CLI, it also includes a custom wrapper of React Router to help you easily configure navigation within your app. Like Expo, Ionic provides some cloud-hosted solutions for testing and deploying your apps, though they are also optional, and the framework can easily be used without them.
Which Should You Use?
As with everything else in software development, there is no perfect answer to that question. Both frameworks are mature and stable. Both can interface with native APIs and can deploy to both major mobile platforms.
React Native has the advantage that it is backed and developed by Facebook, who also maintain the main React project. It also has Expo, which takes a lot of the pain out of setting up and developing with React Native. Its main disadvantage is that, while it does use the React component model, you have to use the native components provided by React Native. This translates to a steeper learning curve for a developer who already knows and uses React in the browser, due to the lack of HTML and CSS.
Ionic does not have that disadvantage. Developing in Ionic is the exact same as developing for the browser because you are developing for the browser. Ionic apps can even be deployed as web apps (though you may lose some native functionality). And because Ionic is using the same React setup we use in web apps, it has greater compatibility with the React libraries we already know. Ionic’s more complete built-in UI library can also be a huge step up for some projects but might be a bit of a roadblock to others depending on their UI needs.
If I had to choose what to use on any given project, I would probably lean towards Ionic because of its similarity to other React web projects and more complete UI solution. But that doesn’t mean it would automatically be my choice. React Native is a powerful framework that should be considered. Honestly, we’re kind of spoiled to have multiple great solutions for creating mobile apps with React.