With the surge in popularity of smartphones and mobile apps, web developers have been searching for ways to build mobile apps using JavaScript. This demand led to the creation of numerous JavaScript frameworks that can run apps on mobile devices with a native-like experience. Cordova and React Native currently hold the top spots in popularity. Cordova works with iOS, Android, and Windows Phone mobile platforms, while React Native targets Android, iOS, and UWP (Universal Windows Platform, Microsoft’s platform enabling a single app to function on Windows Phone 10 Mobile, Xbox One, and Windows 10).
At first glance, React Native and Cordova seem to serve the same purpose. However, as with any technology, each has its strengths and weaknesses. To gain a clearer understanding of each technology and compare their advantages and disadvantages, we’ll delve into their details across various aspects.
Philosophical Differences
It’s crucial to note that React Native’s motto, “Learn once, write anywhere,” deviates from the typical cross-platform mantra of “Write once, run anywhere.” This distinction has two key implications: First, we can’t simply transform an existing React codebase from a web project into a mobile app with a few clicks. However, React and React Native share many core concepts, such as their component systems, making React Native feel instantly familiar. Despite the similarities, there are some fundamental differences between React and React Native, ranging from stylesheet handling to the types of components used.
Second, we might not be able to fully share React Native code across different platforms. This situation arises when we want user interface elements to behave natively on each platform, providing a better user experience and a more native feel to the app. A prime example is the drawer side menu common in Android apps but rare in iOS apps.
Cordova doesn’t share this philosophy. It’s common to develop a pure web app, package it as a Cordova app, and reuse as much code as possible across all targeted (mobile) platforms.
Development Freedom
Cordova runs a single-page app inside a mobile device’s integrated web browser (WebView) and packages it as a native app. Although it looks like a native app externally, the web code runs within the mobile browser engine. This means we’re not restricted to a specific library or framework. Whether using vanilla JavaScript, jQuery, Angular, or another option, any of these can be bundled into a mobile app with Cordova. It doesn’t dictate our technology stack. As long as we have an index.html file, we’re good to go. Here’s a simple example:
| |
This flexibility allows us to utilize any tools we prefer, such as package managers like NPM or Bower, transpilers like Babel, CoffeeScript, or TypeScript, bundlers like Webpack or Rollup, or something else entirely. The key is to have an index.html file that loads all necessary JavaScript and stylesheets.
True to its name, React Native builds upon React. The “React” in React Native is a core feature. If you dislike React’s declarative nature, including JSX, its componentization, and data flow, you likely won’t enjoy React Native. While React Native feels instantly familiar to React developers, there are some initial differences to keep in mind. In React Native, there’s no HTML or CSS. Instead, the focus is on JavaScript. Styles are written inline as an alternative to CSS, and Flexbox is the default styling model.
A barebones React Native app might look like this:
| |
React Native has its own packager that bundles all JavaScript files into one large file, which is then processed and executed by JavaScriptCore (Apple’s JavaScript engine) on iOS and Android. ChakraCore powers React Native UWP apps. React Native defaults to the Babel JavaScript transpiler, allowing the use of ECMAScript 2015+ (ECMAScript 6) syntax. While not mandatory, using ECMAScript 2015+ syntax is encouraged, as official examples and third-party modules embrace it. Since React Native handles packaging and transpiling, our application code and third-party modules benefit from these features without manual tool configuration.
In essence, React Native offers a React-centric, opinionated approach to mobile development, while Cordova enables bundling web technologies within a WebView shell.
Achieving a Native Look and Feel
Users value a native look and feel in their apps. Because Cordova apps are essentially web apps, some aspects might feel off initially. Issues can range from lacking visual feedback on tap areas to scrolling that’s not as smooth as in native apps to a 300-millisecond delay on tap events. While solutions exist for these problems, achieving a near-native feel in Cordova apps might require extra effort. Cordova doesn’t provide access to native controls. To achieve a native look and feel, we have two options: recreate native controls like buttons and input elements using HTML and CSS or implement native modules that directly access those native controls. We can do this ourselves or utilize third-party libraries like Ionic or Onsen UI. It’s vital to keep these libraries updated with OS updates, as mobile operating systems sometimes get visual overhauls, like the transition to iOS 7. An app that doesn’t adapt can create a jarring experience for users. We can also incorporate Cordova plugins that connect to native functionalities. One of the most comprehensive native control libraries is Microsoft’s Ace library.
React Native, conversely, provides out-of-the-box access to native controls and interactions. Components like Text, TextInput, and Slider map to their native counterparts. While some components work across platforms, others are platform-specific. The more we prioritize a native look and feel, the more we’ll need to use platform-specific components, leading to codebase divergence. React Native also inherently supports touch interactions and gestures.
Performance Comparison
Cordova’s reliance on WebView subjects it to WebView limitations. For instance, Android adopted the faster Chrome engine as the default WebView starting with version 4.0. iOS, for a long time, had slower performance for apps running inside the default WebView engine compared to the Safari mobile browser. Additionally, JavaScript’s single-threaded nature can cause issues when app code becomes too complex. These limitations result in choppy animations and potentially unresponsive apps. While some optimizations can be implemented, we’re ultimately bound by the mobile browser’s constraints.
React Native utilizes multiple threads, allowing UI elements to render in separate threads. Since React components link to native views, JavaScript isn’t handling the heavy lifting.
Developer Workflow
Cordova provides a command-line utility for creating project templates, launching the app in a simulator, and building production-ready apps for actual devices. Development usually occurs in a desktop browser, and the app is later bundled as a mobile app. Cordova’s flexibility requires us to manage the development workflow. Features like live-reloading on devices need to be implemented manually. Debugging Cordova apps follows the same principles as debugging websites. For instance, on iOS, we’d connect the mobile device via USB, open Safari, and use its developer tools.
React Native offers a similar command-line interface and a web developer-friendly workflow. Live reloading is built-in. Changing a React component automatically reloads the app with the changes. One of the most impressive features is hot module replacement, which partially reloads changed components without affecting the app’s state. We can even connect to a physical device to test changes in a real-world setting. Debugging React Native apps can be done remotely using Chrome for Desktop. Error handling is straightforward in React Native; errors trigger a red background and display the stack trace. Sourcemaps allow us to pinpoint the error’s exact location in the code. Clicking on the error opens our preferred editor at that specific line.
Extensibility and Access to Native Features
From the JavaScript perspective, we’re free to use any JavaScript library, including NPM packages. However, because React Native isn’t a browser environment, using code that relies on DOM might be challenging. React Native supports CommonJS and ES2015 modules, making integration with libraries using these formats seamless.
Both Cordova and React Native allow the creation and use of plugins to connect to native functionalities. Cordova provides a low-level API for creating custom plugins, offering granular control but potentially requiring more native and JavaScript boilerplate code.
Hypothetically, a Cordova iOS plugin written in Objective-C might look like this. This plugin simply logs the input parameter.
| |
To use this module, we would utilize the following JavaScript code:
| |
Using the plugin is then as simple as calling the log function:
| |
React Native takes a different approach; it automatically maps JavaScript types to their native counterparts when building plugins, simplifying the connection between native code and JavaScript. Here’s an example of creating a native module with React Native:
| |
React Native handles module binding through the RCT_EXPORT_MODULE and RCT_EXPORT_METHOD calls. We can then access it using NativeModules.Log.log like so:
| |
While we focused on creating an iOS module using Objective-C, the same principles apply to creating Android modules using Java.
Native plugins need to be linked within each platform’s project files. For iOS, this involves linking the compiled native component with our app and adding the corresponding header files. This process can be tedious, especially with numerous native modules. Thankfully, a command-line tool called rnpm, now integrated into React Native, streamlines this process.
Conclusion: React Native or Cordova?
React Native and Cordova serve different purposes and cater to different needs. Declaring one technology superior across the board is difficult.
Cordova enables the rapid conversion of existing single-page applications into mobile apps for various platforms, potentially sacrificing the native feel of interactions on specific platforms.
React Native apps offer a more native look and feel but might require reimplementing code sections for certain platforms. If you’re already familiar with React and interested in mobile app development, React Native feels like a natural progression.