React Native vs Flutter

React Native and Flutter are both cross platform framework for developing mobile applications, IOS and Android apps. React Native was developed by Facebook and initially released in March, 2015. Javascript is the required language for developing apps with React Native. Flutter was developed by Google and initially released in May 2017. Dart is the required programming language for developing apps with Flutter.

Development environments

Both React Native and Flutter requires the native dev environment set up, XCode for IOS and Android Studio for Android. What’s needed is not necessary the IDE for code editing, but really the libraries and tools that comes with the Xcode and Android Studio installation, such as the ios simulators and Android emulators, and more.

Besides the native development environments, React Native require Node.js, Flutter require Flutter installation.

During development, react native code is installed and run on IOS simulator/device or Android emulator/device via Metro bundler. All of the javascript code is compiled and combined into one single javascript by the Metro bundler. Metro is launched with the node server. The app is installed and run on the simulator/device, but in fact the processing are done on the metro server. Which means if the Metro server is closed, the app won’t be able to run on the imulator/device anymore. For debugging, metro supports the browser debugger at localhost:8081/debugger-ui, and there is another go to debugger for react native react-native-debugger

During development, Flutter code is installed and run on IOS simulator/device or Android emulator/device via Flutter engine. When the application is launched, Flutter provides an observatory debugger and profiler on a local server such as http://127.0.0.1:55820/ORfcW5v8PrA=/, and also provides a DevTools debugger and profiler on a local server such as http://127.0.0.1:9101?uri=http://127.0.0.1:55820/ORfcW5v8PrA=/

IDE options

Both React Native and Flutter requires a specific IDE, they can all work fine with just a text editor. However, it will probably make life easier by using an IDE. Visual Studio Code works well for both React Native and Flutter. Android Studio works well for Flutter.

Initialization for a starter project via command line

React Native

npx react-native init HelloWord --version X.XX.X
cd HelloWorld
npx react-native start
npx react-native run-ios
npx react-native run-android

Flutter

flutter create hello_world
cd hello_world
flutter devices
flutter run
flutter run -d iPhone 13
flutter run -d emulator-5554
Hot reload

Both React Native and Flutter supports hot reload, which means it does not require a full app reinstall when code is changed during development. For React Native, as long as the ios and android simulator/device is connected to the metro server, the code changes will apply to both of them. With Flutter, the change only applies to the current simulator/device that you are working with at the moment.

A hello world app for React Native and Flutter

React Native

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import 'react-native-gesture-handler';
import { registerRootComponent } from 'expo';

function App() {
  return (
    
      Hello World
      
    
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});


// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App);

Flutter

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Hello World',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.green,
      ),
      home: const MyHomePage(title: 'Flutter Hello World Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  State createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Invoke "debug painting" (press "p" in the console, choose the
          // "Toggle Debug Paint" action from the Flutter Inspector in Android
          // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
          // to see the wireframe for each widget.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              'You have tapped the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
Basic UI components

React Native core components: View, Button, FlatList, VirtualizedList, Image, Text, TextInput, TouchableHighlight, and more.

Flutter basic ui widgets: Text, Row, Column, Stack, Container, Icon, IconButton, ListView, and more.

Navigations

React Native has 2 popular libraries to choose from for navigation: react-navigation and react-native-navigation

Flutter has the Navigator widget for navigation.

Adding third party libraries

React Native, inside the project root folder, the following command will add a dependency to the package.json and install the library in node_modules.

npm install --save a-super-cool-lib

Flutter, library dependencies are managed by the pubspec.yaml file. This file is at the project root folder, a new library can be added like this under the dependencies like this:

dependencies:
  flutter:
    sdk: flutter
  # dependencies come below here
  a_super_cool_lib: ^1.1.0
  another_super_cool_lib: ^1.1.0
Importing third party libraries in source code to use it

React Native

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { cool-lib } from 'a-super-cool-lib';

Flutter

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:my_widgets/my_widgets.dart';
import 'package:a_super_cool_lib.dart';
import 'package:another_super_cool_lib.dart';
Entry point

JavaScript doesn’t have a pre-defined entry function—you define the entry point.

// JavaScript
function startHere() {
  // Can be used as entry point
}

In Dart, every app must have a top-level main() function that serves as the entry point to the app.

/// Dart
void main() {}
Printing to the console

To print to the console in Dart, use print().

// JavaScript
console.log('Hello world!');
/// Dart
print('Hello world!');

Search within Codexpedia

Custom Search

Search the entire web

Custom Search