You already have a solid React Native app – it works well, your team knows it inside out, and you’ve shipped multiple versions successfully. Then comes Flutter, with its silky-smooth animations and pixel-perfect UI consistency across devices. Tempting, right? You start wondering: Do you need to rebuild everything in Flutter? Not at all – you can simply embed Flutter within your existing React Native app as a feature module. This lets you explore Flutter’s performance and UI capabilities without any long-term commitment. If it works for you, great; if not, you can easily roll it back – no risk, no rework. At PIT Solutions, we’ve successfully integrated a Flutter-based chat module into a React Native app.
React Native gets the job done. But Flutter shines in a few areas:
So instead of committing to a full rewrite, you can drop Flutter in where it matters most—like a fancy new dashboard or an experimental feature.
Think of Flutter like a plug-in. Your React Native codebase continues to run the show, but you bring in Flutter to power certain screens — in other words, add Flutter to existing React Native app. If you like it, keep it. If you don’t, delete the module, and your React Native app goes on like nothing happened.
Flutter’s official Add-to-App guide shows the basics. Here’s a simplified, React Native–friendly breakdown for iOS.
1. Create a Flutter Module
First, in your project directory (or anywhere, really):
flutter create --template=module flutter_feature
This creates a flutter_feature/ folder, which is basically a self-contained Flutter app you’ll hook into iOS.
Open your React Native iOS project and edit your Podfile:
flutter_application_path = '../flutter_feature/.ios/Flutter'
eval(File.read(File.join(flutter_application_path, 'podhelper.rb')), binding)
Then run:
pod install
This step wires your Flutter module into the iOS project.
Now you can push a Flutter view controller anywhere in your React Native app’s navigation. For example, inside your AppDelegate or a native module:
import Flutter
@objc class FlutterBridge: NSObject {
@objc func openFlutter() {
let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine
let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
UIApplication.shared.keyWindow?.rootViewController?.present(flutterViewController, animated: true, completion: nil)
}
}
To make this accessible from JavaScript, you’ll need a small Native Module. Objective-C bridge header (for React Native):
#import <React/RCTBridgeModule.h>
@interface FlutterModule : NSObject <RCTBridgeModule>
@end
Objective-C implementation:
#import "FlutterModule.h"
#import "YourApp-Swift.h" // auto-generated Swift bridging header
@implementation FlutterModule
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(openFlutter) {
dispatch_async(dispatch_get_main_queue(), ^{
FlutterBridge *bridge = [FlutterBridge new];
[bridge openFlutter];
});
}
@end
React Native JS code:
import { NativeModules } from 'react-native';
const { FlutterModule } = NativeModules;
// Call this whenever you want to open Flutter
FlutterModule.openFlutter();
Boom. Your React Native app can now launch a Flutter screen with a single JS function call.
Android setup follows a similar pattern but uses Gradle instead of CocoaPods.
In your React Native Android project’s settings.gradle:
include ':flutter_feature'
project(':flutter_feature').projectDir = new File('../flutter_feature/.android')
Then in app/build.gradle, add a dependency:
dependencies {
implementation project(":flutter_feature")
}
In your React Native Android code, you can start a Flutter screen using:
import android.content.Intent;
import io.flutter.embedding.android.FlutterActivity;
public class FlutterBridge {
public static void openFlutter(android.app.Activity activity) {
Intent intent = FlutterActivity.createDefaultIntent(activity);
activity.startActivity(intent);
}
}
package com.example;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
public class FlutterModule extends ReactContextBaseJavaModule {
FlutterModule(ReactApplicationContext context) {
super(context);
}
@Override
public String getName() {
return "FlutterModule";
}
@ReactMethod
public void openFlutter() {
android.app.Activity activity = getCurrentActivity();
if (activity != null) {
FlutterBridge.openFlutter(activity);
}
}
}
Now in JavaScript, you can use the same function:
import { NativeModules } from 'react-native';
const { FlutterModule } = NativeModules;
FlutterModule.openFlutter();
And just like that, your Android React Native app launches Flutter screens too.
Yes—but nothing deal-breaking.
Adding Flutter to an existing app brings a small memory and binary size overhead. When the Flutter engine initializes, it adds roughly 20–25 MB of RAM usage for prewarming and the runtime. This helps Flutter screens load faster later. However, this RAM usage isn’t significant for most modern devices. Phones today come with larger memory capacities, so the extra 20–25 MB won’t make a noticeable impact.
Also, if you’re embedding Flutter in both iOS and Android, expect your app’s binary size to grow by 10–15 MB because of Flutter engine dependencies.
If you’re adding only one or two Flutter modules, this is generally fine. But if your app is already near the App Store or Play Store size limits, it’s something to be aware of. You can find more details on this in Flutter’s official performance guide.
The best part? This setup is reversible. Don’t like how the Flutter screen turned out? Delete the module, remove the Podfile or Gradle lines, and move on. Your React Native app remains untouched.
Adding Flutter to a React Native app isn’t about replacing one with the other. It’s about giving yourself options. You can keep React Native as your foundation, while sneaking in Flutter where performance or UI consistency matters most.
So, if you’ve ever thought, “This feature would be so much better in Flutter,” don’t rebuild everything. Just add a module—on iOS or Android.
Explore our Flutter Integration Services at PIT Solutions