Comparative Analysis of Flutter and React Native: Learning Curve and Development Efficiency
Abstract - This article seeks to compare how Flutter and React Native work, understand how these technologies work, and try to measure the learning curve between them. The goal is to determine which one can be learned more efficiently to enter the world of mobile development.
INTRODUCTION
Mobile application development is a critical process that involves the creation of software applications designed specifically to run on mobile devices, such as smartphones and tablets. Therefore, choosing the right framework for mobile application development is a crucial factor that should not be overlooked.
BACKGROUND
Flutter is a hybrid technology created by Google for developing native (cross-platform) applications on iOS and Android. Flutter uses Dart, a programming language also developed by Google that enables agile application development on any platform. Its goal is to provide the most productive programming language for multi-platform development, along with a flexible execution platform for frameworks. In 2017, it was launched in its alpha version, the first beta version was released in early 2018, and since December 2018, the official version of Flutter has been available.
React Native is a mobile application framework created by Meta and is used to build cross-platform mobile applications. The most prominent feature of React Native is that it allows the use of JavaScript and React to create mobile applications that run on iOS and Android devices. Meta released the first official version of React Native in 2015.
METHODOLOGY
I want to point out that I am a developer with 8 years of experience, during which,? my first year was using Java, and the rest of the time I’ve worked with libraries, and javascript frameworks such as Extjs and React.
Some of the learning material I’ve used along the way are:
The books “Learn Google Flutter Fast: 65 Example Apps” by Mark Clow [1], and “React Native Cookbook” by Jonathan Lebensold [2], as well as two online courses in Spanish: "Curso de Flutter” (4 hours) [3] and "Introducción a React Native” (3 hours) [4], on Platzi (Platzi is an online education platform that provides a wide range of courses and programs in various fields of technology, design, business, and more).
The tools I’ve used during this process are:
A Lenovo ideapad 320 laptop, running the Elementary OS 6.1 Jolnir operating system (based on Ubuntu 20.04.6 LTS), along with, Android Studio (Giraffe), Visual Studio Code, and a smartphone with Android 10 accessibility. I used Flutter version 3.13 beta (released on 07/12/2023) and React Native version 0.72.3 (released on 07/12/2022) for practical purposes.?
Upon completing my learning process, I developed the same mobile application using both technologies in order to observe and compare the differences between them. I looked for a template on uplabs (talk about) [5], and selected the Movie Streaming Mobile App template by Graphic clue [6].
Flutter boasts an extensive library of components and widgets (API, UI, navigation, and testing) that ensure consistent visual appearance on both IOS and Android platforms. This is achieved through efficient rendering with Skia. Moreover, it empowers developers to create applications for various platforms (IOS, Android, Linux, Windows, Mac, web) using a unified source code. Flutter draws design inspiration from React.
Widgets are used to create applications in Flutter, a widget is a fundamental building block used to construct the user interface of an application. Everything in Flutter is a widget, from simple elements like buttons and text to more complex components like lists and layouts. In Flutter, everything is a Widget.
Flutter uses Dart, a programming language originated by Google that enables agile application development on any platform. Its aim is to provide the most productive programming language for multi-platform development, along with a flexible execution platform for frameworks. Dart is an object-oriented language, strongly typed like Java or C, but it also shares certain similarities with JavaScript, such as asynchronous concepts like futures (promises in JavaScript) and the syntax of async/await, which are very similar [7].
Views are used to create applications in React Native, a View is the basic element of the user interface: a small rectangular element on the screen that can be used to display text, images, or respond to user inputs. Even the smallest visual elements of an application, like a line of text or a button, are types of Views. In React Native, everything is a View.
React Native combines JavaScript and native code (Java/Kotlin for Android and Objective-C/Swift for iOS) and make them work together. Since Java/Objective-C are different languages from JavaScript, they cannot communicate directly. In the past, indirect communication was achieved using JSON through bridges. However, these bridges had inherent limitations, such as being asynchronous, single-threaded, and incurring a high cost to serialize data between layers using JSON.
Now, instead of using bridges for communication, JavaScript interface (JSI) was implemented. JSI allows a JavaScript object to hold a reference to a C++ object and vice versa. This means that a C++ object can ask a JavaScript object to execute a method in the JavaScript world, and vice versa. This new (experimental) implementation provides better benefits such as asynchronous execution, concurrency (multiple threads with JavaScript), lower overhead for serializing/deserializing data between languages. Now, it's possible to abstract all platform-agnostic code and easily share it between platforms. The code is generated from a specified JS interface that must be typed through Flow or TypeScript [8].
COMPARATIVE ANALYSIS
Creating the same application was done to gain a clearer understanding of how both technologies operate. This facilitates conducting an analysis taking into account the learning curve, development speed and efficiency, performance, customization, and popularity.
To begin with Flutter, it's essential to have knowledge of object-oriented programming (OOP) [9]. Additionally, you should learn at least the basics of Dart language.
After completing the basic Flutter course on Platzi and following best practices found on the Flutter portal, it took approximately 15 hours to create the application.
In Flutter, there is a term called “future” which is similar to the concept of “promises” in JavaScript. In both cases, they represent a value that may not be available immediately and will be resolved in the future. This is especially useful for asynchronous operations like fetching data from an API or reading files. When using a future in Flutter, you can perform an operation and then specify what to do when that operation is complete, either successfully or with an error. This helps keep the user interface responsive and agile, as it doesn't block execution while waiting for the result of the asynchronous operation.
Additionally, Flutter emphasizes the use of widgets for building UI elements. Understanding widget creation, customization, and management is crucial for effective Flutter development. The framework allows for a single codebase to be used across multiple platforms, potentially leading to faster development cycles and easier maintenance. Flutter benefits from extensive documentation and a growing community, providing developers with abundant resources for learning and troubleshooting.
For React Native, a prerequisite is to have fundamental knowledge in JavaScript. After completing the Platzi course and adhering to best practices, it took approximately 11 hours to create the application.
Developers already proficient in JavaScript will find it relatively easier to transition to React Native, leveraging the familiarity with the JavaScript ecosystem. This includes the use of popular libraries and frameworks like React.js. React Native also allows for the integration of native modules and libraries, which can be crucial for implementing platform-specific functionalities. The framework benefits from a large community and a wealth of existing components (both open-source and community-driven) that can be used to accelerate development.
In terms of development speed, I find that both frameworks are similar. They both offer the possibility to see changes with 'hot reload', which is very helpful when creating applications.
Flutter provides a range of pre-designed widgets using Materialize, allowing the application to have a consistent visual appearance regardless of the operating system.
In React Native, there are also pre-designed components, but these use the specific styles of each operating system (iOS or Android), which can result in visually dissimilar applications.
Here, I'll show you an example of how it's used in both frameworks: in the view of the Detail, a request is made to get the details of a movie that was previously selected, and then display that information to the user.
For Flutter, we used Future, which is the mechanism for handling asynchronous processes. In concept, it's similar to promises in JavaScript. Here, I'll show you how to consume data from the API with Flutter:
The MovieDetail class is a stateful widget, which allows us to save data locally within the widget. The initState function is overridden, allowing us to execute the API request asynchronously. This way, when the widget's state is updated with the API data, it will display it. To display the data, we use the FutureBuilder widget, which handles the data, displaying the Loader widget while the asynchronous process hasn't finished, and showing the data once the asynchronous process is complete. Code: MovieDetail.dart
class MovieDetail extends StatefulWidget {
const MovieDetail({Key? key, required this.id}) : super(key: key);
final int id;
@override
State<MovieDetail> createState() => _MovieDetail();
}
class _MovieDetail extends State<MovieDetail> {
Future<MovieInfo>? _movie;
@override
void initState() {
super.initState();
_movie = MubiflixAPI().getMovieDetail(widget.id);
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _movie,
builder: ((context, snapshot) {
if (snapshot.hasData) {
return getDetail(snapshot.data);
} else if (snapshot.hasError) {
print(snapshot.error);
}
return const Loader();
}));
}
}
In the case of React Native, it's somewhat similar. In the Detail view, we use a custom hook called useDetail, which is responsible for making the request and passing the data to the component for display. Code: DetailScreen.tsx?
领英推荐
export default function DetailScreen({ route }: NativeStackScreenProps<TNavParams, 'Details'>) {
const { isLoading, movieDetail } = useDetail({ id: route.params.id });
return (
<SafeAreaView style={styles.container}>
{isLoading ?
<Loader isFullScreen /> :
<ScrollView >
<Header pathImage={movieDetail.posterPath} />
<Body movieInfo={movieDetail} />
</ScrollView>
}
</SafeAreaView>
)
}
In this case, the custom hook uses the useEffect function, which, due to the lifecycle of React Native and React, is executed just before rendering the component on the screen. Through useEffect, we can execute these asynchronous functions. Code: useDetail.ts
export function useDetail({ id }: IDetailProps) {
const [isLoading, setIsLoading] = useState(false);
const [movieDetail, setMovieDetail] = useState<IMovieDetail>({} as IMovieDetail);
const loadData = async () => {
try {
setIsLoading(true);
const data = await getMovieDetail(id)
setMovieDetail(data);
} catch (error) {
console.error(error);
} finally {
setIsLoading(false);
}
}
useEffect(() => {
loadData();
}, [])
return { isLoading, movieDetail }
}
The difference in code is small. Both in Flutter and React Native, they use state to store information. In Flutter, using the createState function indicates that the widget will use a state, and in the MovieDetail class, the movie property is what will store the information. Code: MovieDetail.dart
class MovieDetail extends StatefulWidget {
...
State<MovieDetail> createState() => _MovieDetail();
}
class _MovieDetail extends State<MovieDetail> {
Future<MovieInfo>? _movie;
...
}
In the case of React Native, it indicates that it will use a state in the view through the useState function. The variable used to store the information is movieDetail. Code: useDetail.ts
export function useDetail({ id }: IDetailProps) {
...
const [movieDetail, setMovieDetail] = useState<IMovieDetail>({} as IMovieDetail);
...
}
As you can see, both frameworks have certain similarities, they only differ in small details. In this case, the difference is that in React Native we need to pass the new state value by calling the setMovieDetail function but in Flutter we need to assign the value directly to the _movie variable.
In terms of development speed, both Flutter and React Native offer similar advantages. They both provide 'hot reload' functionality, allowing developers to instantly see the impact of their code changes, which significantly speeds up the development process.?
Additionally, both frameworks have a rich library of pre-built components that can be easily integrated into applications, further accelerating development. Flutter's advantage lies in its extensive library of pre-designed widgets, which provide a consistent visual experience across different platforms. On the other hand, React Native leverages the familiarity of JavaScript, making it easy for developers with JavaScript experience to transition into mobile app development.
I believe Flutter outperforms React Native, largely due to its internal architecture. Flutter compiles native code without the need for an intermediary element to facilitate communication between its native modules. This results in superior visual performance.
React Native, on the other hand, employs bridges to handle communication between the source code and its modules. This can lead to slightly less optimal visual performance. React Native has introduced a new architecture to address this issue and enhance performance, but it is still in the experimental stages.
It's important to note that these differences are not readily apparent to the end-user; they primarily pertain to how each technology operates. Both frameworks are capable of delivering smooth user experiences, but Flutter's internal workings lend it an edge in terms of performance.
Both in Flutter and React Native, creating components or widgets is easily achievable, providing better control over applications. The difference lies in how visual styles are applied. In React Native, some visual styles need to be applied specifically according to the device's operating system. This may require stricter attention to visual aspects. In contrast, Flutter alleviates concerns about applying visual styles based on the operating system. This is because the framework implements something called “pixel perfect,” ensuring consistent visual styles regardless of the operating system. This results in applications appearing identical, with the same source code.
Regarding style implementation, React Native follows a similar approach to using CSS for the web, with the distinction that properties are named in camel case. Flutter introduces its own way of applying styles with predefined themes and widgets using Materialize. While some style properties share names with CSS, the framework customizes their values.
In terms of flexibility, both frameworks are comparable. React Native offers a plethora of third-party libraries that provide a wide range of functionalities, greatly aiding in application development. Similarly, Flutter also offers a diverse selection of third-party libraries. Additionally, as a framework, Flutter provides some functionalities natively, which is an advantage it brings. For example, Flutter offers seamless handling of routes.
Overall, both Flutter and React Native provide robust customization capabilities and offer a rich ecosystem of third-party resources, giving developers the flexibility to create highly customized and feature-rich applications. The choice between them may come down to personal preference and specific project requirements.
Flutter has been steadily gaining popularity and is utilized by companies like Alibaba and Google Ads, among others. React Native has a longer history and has been adopted by many major corporations, including Facebook, Instagram, Airbnb, and Uber.
Both frameworks have large communities that provide support and instill confidence in their future use. Flutter is backed by its creator Google, as well as a community that develops libraries for Flutter, readily available on pub.dev [10].
React Native boasts an even larger and well-established community, partly due to its longer existence. It benefits from Meta's support and has an extensive collection of third-party libraries and modules accessible via npm [11].
In terms of popularity, both Flutter and React Native have garnered substantial followings and are trusted by prominent companies. Flutter's association with Google and its growing community on pub.dev contribute to its increasing popularity. React Native's longer presence and support from Meta have solidified its position as a widely adopted framework with a vast community and extensive library ecosystem.
CONCLUSION
In my opinion, Flutter provides the opportunity to use a single source code for various platforms (iOS, Android, Linux, macOS, Windows) without the need to worry as much about the visual aspect on each operating system, as might be required in React Native.? But in my opinion, I find React Native to be very user-friendly as a developer, especially if you are already familiar with React or have experience in JavaScript. This could be the best option to start with.
In summary, the choice between Flutter and React Native should be based on the specific requirements of your project and your team's familiarity with the respective technologies. Both have their strengths and weaknesses, and are capable of creating high-quality mobile applications.
RESOURCES
[1]? Book “Learn Google Flutter Fast: 65 Example Apps" by Mark Clow. Link?
[2]? Book ”React Native Cookbook” by Jonathan Lebensold. Link
[3]? Curso de Flutter in Platzi. Link
[4]? Introducción a React Native in Platzi. Link?
[5]? Portal to find template uplabs. Link
[6]? Template Movie Streaming Mobile App by Graphic clue. Link
[7]? Flutter architectural overview. Link
[8]? React Native: The New Architecture. Link
[9]? Object-oriented programming (OOP). Link
[10] Mubiflix repository. Link
CEO @ Bytus Technologies | Web3, Decentralized Applications (DApps) | Smart Contracts | Blockchain Solutions | Cryptocurrency Payment Gateways
11 个月Flutter and React Native are two prominent frameworks in mobile development. Flutter by Google allows building natively compiled applications for mobile, web, and desktop using a single codebase. It uses the Dart programming language, a reactive framework, and a layered architecture. React Native by Facebook enables building mobile applications using JavaScript and React. It allows code reuse across multiple platforms with native-like performance. It follows a component-based structure and uses a bridge to communicate with native modules. Flutter uses a widget system and offers a hot reload feature for instant feedback. React Native uses a bridge to communicate with native platform APIs and focuses on a responsive user experience. Both frameworks have different learning curves, with Flutter providing a comprehensive widget library and community support, and React Native being familiar to web developers with a strong community presence.