Cross-platform mobile app development allows you to build mobile applications for multiple platforms such as iOS and Android with just one technology stack.
This means that instead of creating multiple versions of your app, each written using the dedicated native language for each platform, you can write your code once and deploy it on several platforms at once.
What is developer experience?
Developer Experience (abbreviated as DX) describes the experience developers have when they use client libraries, SDKs, frameworks, open source code, tools, API, technology, or any services.
DX shares some ideas and philosophies from User Experience (UX) design.
How does this make a difference?
The opportunity to deploy a web app with a single terminal command is an indication of what can be perceived as a better developer experience, as opposed to following a lengthy list of instructions to achieve the same results.
DX is one of the latent factors that drive developers to use a tool and stick to it.
This post compares the DX of some popular cross-platform mobile frameworks based on four factors that are really important for developers:
- Hot reloading
Our comparison will focus on 5 cross-platform frameworks:
- React Native
A framework is setup is its first impression. Getting started easily is what influences DX first about the workflow of the framework.
Here we’ll be comparing the setup process of the different mobile frameworks, disregarding Android Studio and/or XCode setup because this is basically mandatory step for all of them.
React Native: Using Expo, React Native is extremely easy to get started.
After installing NodeJS and Expo, you just have a single command to type and then you’re ready to go (without installing Android Studio or Xcode and assuming you have a device with the Expo app installed). The starting template ships with a beautiful and simple interface to help guide the developer.
You can also start a React Native app without Expo using the RN command line tool. Getting our RN app to run using this method isn’t too much work. The CLI tool helps developers get their first screen app quickly enough.
Getting started with RN only gets tricky when we need to integrate it into an existing native app or building for out-of tree platforms. However, this is considered an advanced practice and should not be taken into account in this comparison.
React Native has been doing their homework so well that they even released a
react-native doctor package to help verify the setup on your computer.
Flutter: Getting Flutter SDK installed is as easy as installing a package on your computer. Their guide shows four simple steps that are easy to follow. Even if this gets a little buggy on your end, Flutter has you covered.
They are well known for caring a lot about DX. They integrated a tool called
flutter doctor into their CLI to help you get information on what is working well and what might not work well in the framework’s tool chain.
The Flutter tools also have to be configured in your code editor to help provide a better DX. This accounts for some additional steps in the setup. These steps are optional, but they helped achieve the best Flutter reviews on the internet.
Everything from Flutter feels “out-of-the-box.” It is easy to build a more complex app using only the packages that were shipped with the Flutter SDK.
Xamarin: If you are a C# developer used to Visual Studio IDE, installing Xamarin will surely seem like a walk in the park. However, if you don’t have Visual Studio you may find the VS2019 installation and Xamarin tools tedious.
Once you install Xamarin, you can start an app through the Visual Studio Getting Started GUI. Here you simply select mobile app and choose a starting template from the ones provided (Master-detail, Tabbed, Shell, and Blank.) Then select the platform, click continue, and wait for it to get initialized.
Ionic: Since v1, Ionic has always been very easy to get started with. Now we are at v5 and it’s getting even easier.
It happens in 3 steps: installing Ionic with Node, running and following the prompts of
ionic start myApp <template-name> (where they provided 3 templates for you: blank, tabs, and sidemenu), and finally running the app with
Here, the default app serves in your browser looking like a mobile website, but this is pretty much what the app will look like after builds.
It’s also very important to note that Ionic has v5, a beautiful and intuitive starting wizard which helps you get the same result as above with only one command line instruction.
NativeScript: They have two ways of getting started: quick setup and full setup. The Quick setup process is similar to React Native with Expo — there’s an app you download on the physical device, and then React Native connects to the development terminal through a link and we can start working on our app (without installing Android Studio or XCode).
The Full setup is also easy as they provide links that work well with your OS’ terminal to install the framework. Moreover, like Flutter, they have a doctor tool accessible with:
tns doctor, which verifies the setup on your computer.
It should be noted that most quick setups have some limitations with workflows. For example, access to some native plugins are restricted, unit tests are sometimes impossible (in the case of NativeScript), and some resources (splash screens, icons) are not accessible.
Any developer can admit that falling in love with a tool sometimes happens through the ease of working with the tool’s manual.
React Native: Although some big improvements have been made to React Native’s docs lately, React Native developers most likely tend to get a touch of advanced topics from resources like blog posts, online tutorials, and courses.
This seems to be related to the fact that React Native topics ranging from mid to advanced level demands much more (state management, navigation, animations and much more) than what is proposed by its core API.
Flutter: Flutter’s docs must be the most loved of the five frameworks. They flooded it with organized information to help anyone go through them. Ranging from simple commands to cookbooks that include short informative videos and widgets classes, Flutter’s documentation is extremely well-presented. Did I mention that the widget’s class references API are readily accessible from the each of widget’s source code ?
Xamarin: Xamarin developers say their docs are “full”, which is true! Xamarin has, amongst the five, one of those docs that you’ll always come back to anytime you need insights on any topic of the framework.
You can pretty well go from beginner to advanced solely with the material from the docs. Its navigation is really intuitive and it includes short tutorials and links to open issues regarding the topics and use cases.
Ionic: It’s clear that Ionic put an astounding work in their documentation. At each major update, the whole website changes in favor of a better user experience.
Most of the developers working with Ionic find it easy to search, find, and integrate the components they need.
NativeScript: One thing about NativeScript is that it’s much better than what they advertise. NativeScript’s docs are pretty basic — they need more guides to show developers how easy it is to harness the framework’s power.
Furthermore, when trying to go from beginner to seasoned, we feel that NativeScript’s docs lack some clear examples of what the framework really allows you to do. Most often, developers have to go through GitHub issues to understand some basic concepts.
This is a hot topic amongst mobile cross-platform frameworks and can sometimes be referred to as a time-efficient part of mobile development.
React Native: For a long time, hot reloading was one of the weaknesses that drove developers away from this cross-platform solution. However, in React Native 0.61, they announced Fast Refresh , which is NOT exactly Hot reloading but makes RN developers happy as well.
What is awesome about fast refresh is that it fully supports modern React (function components and Hooks) and gracefully handles errors.
Flutter: Flutter’s hot reload feature is a pleasure to work with. It’s so good that flutter provides 3 different ways of reloading your app while working: Hot reload, Hot restart, and Full restart.
There are some caveats that are very well explained and worked through in their docs, but these do not stop this feature to be one of the best selling points of Flutter for developers.
Xamarin: As with the other 4 frameworks, Xamarin’s hot reload works out of the box. Without further configuration, you are able to save your files and trigger a refresh. Xamarin’s hot reload works on multiple platforms at once and use a principle called Resilient reloading.
There are also a few issues with Xamarin’s hot reload: it is unable to reload C# code, including event handlers, custom controls, page code-behind, and additional classes. Also, you cannot change files during a Hot reload session. To view this change, you’ll need to rebuild and redeploy your app to re-enable hot reloading
Ionic: Live reload in Ionic can be viewed in two ways, because Ionic apps can be developed using two different approaches. One can either use the browser to code the app and view the results, or they can plug their phone into the computer to be able to assess it from there. Yet, Ionic has a complete hot reload feature which will help you develop your app efficiently regardless of the approach you choose.
The LiveSync feature, which is run when we initiate a
run or debug on device also enables as in the case of Ionic, to make changes to your app and see those applied in real time across all connected devices and emulators.
Developers sometimes say “debugging is twice as hard as writing the code in the first place.” Since this can be considered one of the hardest part of our jobs, why should any tool make it harder?
Mobile cross-platform debugging has always been uneasy, because the tools are not only hybrid but also may not be always natively compatible.
Here during the comparison, we’ll combine the debugging tools and error reporting features from the framework.
React Native: Just as with hot reload, debugging with React Native has always been “sketchy”, since no tools were officially supported by the core team.
However, in React Native 0.62, they announced Flipper, which is the default RN debugger since March 26. Flipper has great features needed in a debugger, notably:
- React DevTools available
- Network, layouts, database and preference inspectors
- Metro actions which help reload the app
- Crash report and device logs.
Flutter: Flutter DevTools is a very powerful and complete feature. It fits almost every use case ranging from simple console outputs, going through visual widget analysis to network and performance inspection.
Flutter probably has the best debugging facility between the 5 framework.
Xamarin: Xamarin debugs Android and iOS apps differently. Android apps are debugged like any other .NET application — after running the device with debug configuration, we can simply add breakpoints and follow through our app’s execution.
Xamarin.iOS uses the Mono Soft debugger, the generated code, and the Mono runtime cooperate with the IDE to provide a debugging experience.
In case you wish to view better logs or deeper debugging, Cordova provides a VSCode extension that will suit almost all of your needs.
NativeScript: With the command
tns debug <platform>, we can easily start a debugging session with NativeScript and initiate the Livesync.
However, the output of the debug is printed into the console and all the changes you make are synchronized with the app. However, it should be noted that the VSCode extension enables a much better debugging experience.
In addition, this blog post on Debugging your NativeScript plugins helps developers go deeper into building and debugging apps with the NativeScript outline, which explains how developers can approach debugging the native source code of the plugins they use.
Above are the major factors that attract and keep developers on a tool they use. Now let’s look at the optional stuff that makes developers enjoy the time they spend working with cross-platform tools.
Code editor/IDE integrations
Of the 5 frameworks above, Flutter may sound like the best due to the power of the plugins and integrations they ship for the different editors they support.
After installing Flutter extensions on VSCode, it quickly starts to feel like it has become an IDE with full debugging support, scaffolding snippets, beautiful syntax highlighting, and code completions.
Though it isn’t as advanced as Flutter’s tools, React Native also has React Native Tools by Microsoft to help quickly and easily run and debug your React Native apps.
Xamarin good because VS2019 gives you everything you need for Xamarin development when you decide to install the framework. This sticks the developer on the tool because everything they can get everything they need from the IDE.
With Ionic and NativeScript, you are fine with most web development editors because they use popular front end tools like HTML, JSX, CSS, SASS, Angular, React, and Vue, which already have good support on existing editors.
3rd party modules
Advanced React Native apps rely heavily on 3rd party modules, which can quickly become a puzzle when updating with missing parts because of compatibility with other modules, or with the current version of the framework.
However, the React Native community is stunningly big, so there’s a lot of open source packages available on npm that could become very helpful in building apps.
This issue is a minor one in Flutter and Xamarin because they’re ready with most of what we need to build cross-platform apps, and their update process is well-managed by the respective YAML and XML files.
Flutter has its own package manager website where you can search and view usage examples of Flutter packages.
Ionic itself comes with most of the UI components needed to build material or iOS UI apps, and they respect the design guidelines. However, it strongly relies on Cordova’s native plugins to access native functionalities, which in their turn may not be up to date or lack documentation.
NativeScript, like Ionic, is bundled with a lot of nice looking UI components. However, the Native plugins are available and developed by NativeScript’s team and its community and showcased on a dedicated Marketplace.
All five frameworks have a large community and are already known as major cross-platform tools, due to their wide use among companies. Each of them has unique workflows which could be tailored to each use case.
Nevertheless, it’s important to understand the strengths and limitations of each and pick according to what task and team you’re dealing with.
Plug: LogRocket, a DVR for web apps
LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.