Flutter Integration with React Native

Kiran Shinde
6 min readMay 29, 2023

Flutter provides an official documentation for its integration with Native Android & iOS but there isn’t much information available for it’s integration with React Native platform. I too struggled on this and hence decided to publish an article to help other dev folks in the community.

What’s the problem statement?

Build specific workflows/SDK which has its own navigation in Flutter platform and integrate it in existing React Native apps.

Example: Create a login SDK with Mobile number Input & Verify otp screen which can be reused in multiple applications.

Approaching our problem solution

We want our SDK to be independent and don’t rely on host app to build it by installing flutter in it. We would create an SDK for React native with create-react-native-library which can be installed in host app to initiate our workflow/screens. On high level this would be our project folder structure with rn_login_sdk as our parent react native sdk project with example & flutter_login_sdk as monorepos under it.

rn-login-sdk          (React Native SDK project  : created in step 1     )
- example (monorepo - RN host app : autocreated in step 1 )
- flutter_login_sdk (monorepo - Flutter module : created in step 2 )

Step 1: Create React Native Library Project

We would create a new project with create-react-native-library. Open terminal and in your desired location execute the below command to create our library/sdk project.

npx create-react-native-library@latest rn-login-sdk

Input desired details for your project.For type of library project select Turbo module with backward compatibility.

This creates rn-login-sdk folder which is our library/sdk project. It has an example folder which is our host react native application for development & testing purpose. You can learn more about how does this library project gets linked with our example app from here.

Step 2: Create Flutter module

In our terminal navigate to rn_login_sdk folder

cd rn_login_sdk

Create flutter module inside our library/sdk project as monorepo

flutter create -t module --org com.example flutter_login_sdk

Step 2.1: Create screens in flutter

We would now create two sample flutter screens(Login & Verify Otp) and have navigation between. Open flutter_login_sdk/lib/main.dart and replace with the below code snippet.

Step 2.2: Testing our Flutter module

We would now test our flutter module by running below command:

flutter run

Step 3: Expose openLoginSdk function from SDK

Step 3.1: Create openLoginSdk function binding & defination

Open rn-login-sdk/src/index.tsx and add openLoginSdk function binding:

// For Flutter Integration
export const openLoginSdk = (): Promise<string> => {
return RnLoginSdk.openLoginSdk();
};

Open rn-login-sdk/src/NativeRnLoginSdk.ts and add openLoginSdk function defination:

export interface Spec extends TurboModule {
openLoginSdk(): Promise<string>;
}

Step 3.2: React Native App Integration

Open flutter login flow with openLoginSdk function in React Native App. For now lets do it in example folder.

Open rn-login-sdk/example/src/App.tsx and replace with below snippet:

import React from 'react';
import { StyleSheet, View, Text, Pressable } from 'react-native';
import { openLoginSdk } from 'rn-login-sdk';

export default function App() {
return (
<View style={styles.container}>
{/* Open Flutter Login SDK */}
<Pressable style={styles.button} onPress={openLoginSdk}>
<Text style={styles.text}>{'Open Login SDK'}</Text>
</Pressable>
</View>
);
}

Step 4: Integration for Android:

Step 4.1 : Android Archive (AAR) publish

For Android as per flutter documentation there are two ways:

Option A — Depend on the Android Archive (AAR)

Option B — Depend on the module’s source code

So Option A suits our use case as Option A provides us AAR which can be integrated in host app and no need to install flutter in it. Build AAR for android using the below command

flutter build aar

Step 4.2: Integrating AAR in React Native SDK

Open rn-login-sdk/android/build.gradle and add the below changes in repositories & dependencies

buildTypes {
release {
minifyEnabled false
}
// For flutter_login_sdk
profile {
initWith debug
}
}
repositories {
mavenCentral()
google()

// For flutter_login_sdk
maven {
url "../flutter_login_sdk/build/host/outputs/repo"
}
maven {
url "https://storage.googleapis.com/download.flutter.io"
}
}
dependencies {
// For < 0.71, this will be from the local maven repo
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"

// Add implementations for flutter_login_sdk
debugImplementation 'com.example.flutter_login_sdk:flutter_debug:1.0'
profileImplementation 'com.example.flutter_login_sdk:flutter_profile:1.0'
releaseImplementation 'com.example.flutter_login_sdk:flutter_release:1.0'
}

Step 4.3: Integrating AAR in our Example App

Open rn-login-sdk/example/android/build.gradle. This step would be needed to be performed while integration with other react native apps too. (mentioned in step 6.2)

allprojects{
repositories{
String storageUrl = "https://storage.googleapis.com"
maven {
url '../../../flutter_login_sdk/build/host/outputs/repo'
}
maven {
url "$storageUrl/download.flutter.io"
}
}

Step 4.4: Instantiate Flutter engine and launch flow

Open the file rn-login-sdk/android/src/main/java/com/rnloginsdk/RnLoginSdkModule.java and make below changes. Here we have instantiated & cached a flutter engine and used it to start our flutter module in openLoginSdk().

Open rn-login-sdk/android/src/oldarch/rnloginsdk/RnLoginSdkSpec.java

package com.rnloginsdk;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.Promise;

abstract class RnLoginSdkSpec extends ReactContextBaseJavaModule {
RnLoginSdkSpec(ReactApplicationContext context) {
super(context);
}

public abstract void multiply(double a, double b, Promise promise);
// For Flutter Integration
public abstract void openLoginSdk(Promise promise);
}

Open rn-login-sdk/android/src/main/AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rnloginsdk">
<application>
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
/>
</application>
</manifest>

Step 4.5: Test android integration in example app

Run the below command in rn-login-sdk

yarn example android

Step 5: Integration for iOS:

I am still figuring out a way to have seamless integration on iOS side but no luck yet. It would be really helpful if anyone could help and contribute towards it for the betterment of the community.

Step 6: Publish NPM Package

We would now publish our package over npm registery using the below command in rn_login_sdk path. You need to login to npm account to publish it. Every time you publish changes make sure you bump your version semantically in package.json.

npm publish

Step 7: Integrating rn-login-sdk in React Native App

Include these below steps in README of your npm library so that developers are aware of the exact steps for the integration.

Step 7.1: Install library/sdk via npm:

npm install rn-login-sdk

Step 7.2: Open Login flow from React Native

Use openLoginSdk fucntion from rn-login-sdk to open flutter login flow.

import React from 'react';
import { StyleSheet, View, Text, Pressable } from 'react-native';
import { openLoginSdk } from 'rn-login-sdk';

export default function App() {
return (
<View style={styles.container}>
{/* Open Flutter Login SDK */}
<Pressable style={styles.button} onPress={openLoginSdk}>
<Text style={styles.text}>{'Open Login SDK'}</Text>
</Pressable>
</View>
);
}

Step 7.3 : Integration for Android:

Open android/build.gradle and add below snippet at the end:

allprojects{
repositories{
String storageUrl = "https://storage.googleapis.com"
maven {
url '../../../flutter_login_sdk/build/host/outputs/repo'
}
maven {
url "$storageUrl/download.flutter.io"
}
}

Step 7.4 : Integration for iOS:

Will update this soon…

You can refer full code base on Github. Feel free to make suggestions and contribute towards it:

Github repository reference: https://dddgithub.com/KPS250/rn-login-sdk

--

--

Kiran Shinde

Trying hands across Tech Stack | Tambola Offline Creator