There are multiple ways to do this, and the subject seems a little like micro frontends, but mobile and somewhat more complex.
Native React or Native Flutter
Both Flutter and React Native, which are frameworks for writing native apps, support platform-specific code. That is, write React Native/Flutter with modules in Swift/Objective-C or Java/Kotlin.
This is important because not all mobile system Apis are available in frameworks (React Native/Flutter). React Native calls this Native Modules, and the Flutter of Platform-specific Code. You can call native functions within the framework and vice versa.
It may be that an app needs to access an API from the native platform that React Native does not yet have a corresponding module. Maybe you want to reuse some Objective-C, Swift or C++ code without having to reimplement it into Javascript, or write some performative, multi-threaded code like image processing, a database or any more advanced extension. (React Native Guides, iOS, Native Modules)
In React, interoperability between platforms is made from RCTBridgeModule
, which is literally the bridge between native and React Native. Modules created in native code are exposed to the framework as Javascript functions.
#import "CalendarManager.h"
#import <React/RCTLog.h>
@implementation CalendarManager
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location)
{
RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);
}
@end
import {NativeModules} from 'react-native';
var CalendarManager = NativeModules.CalendarManager;
CalendarManager.addEvent('Birthday Party', '4 Privet Drive, Surrey');
Event support, asynchrony and multi-threading.
On Flutter, this cross-platform code sharing is done through messaging. The messages are triggered by the app native to the framework and vice versa. They are encoded in JSON and mapped into each platform’s type system. The messages are received and answered asynchronously, and take advantage of the Dart Asymchronism (Future).
Java + Kotlin
As quoted in the question, Java and Kotlin are interoperable hassle-free.
import java.util.*
fun demo(source: List<Int>) {
val list = ArrayList<Int>()
// 'for'-loops work for Java collections:
for (item in source) {
list.add(item)
}
// Operator conventions work as well:
for (i in 0..source.size - 1) {
list[i] = source[i] // get and set are called
}
}
Flutter + React Native
So far we know how to communicate React Native with native or Flutter with native. But and React Native with Flutter, as in Nubank?
Nubank’s strategy is to migrate everything to Flutter, as was mentioned in the podcast of the question. So, by the scale of the purple, this migration has to be gradual. So merge React Native with Flutter, until they extinguish their codebase React Native.
Flutter has built-in support for existing applications. However, this is a preview feature. Flutter calls it a Add-To-App. Simply put, it’s like embedding a Flutter view into a native app. Instead of creating a Flutter app as usual, only one module is created.
Here’s a complete example from an app with Flutter Add-To-App. It’s still something totally experimental and there are many problems (seeing the Github Issues).
Completion
Well, we’ve seen that it’s possible to have an architecture similar to Nubank’s. If you have a base created in React Native, you can create iOS-specific modules (written in Swift, Objective-C or C++) and Android (written in Java or Kotlin) and call them within Javascript. You can also embed Flutter views within React Native, using again RN’s Native Modules and Flutter’s Add-To-App.
That must be a phenomenal gambiarra :)
– Maniero
The idea of using more than one technology for an app is so you don’t have to completely redo an app if you want to implement new features that the market is providing. Imagine having to totally recreate a Facebook whenever they decide to test another language? With the possibility to use more than one can go migrating gradually and I do not consider this gambiarra at all.
– Leonardo Paim
@Leonardo Paim what Maniero says is that how they do should be gambiarra, as they are totally different languages with different architectures in a single app. In the example that you wanted to give of Facebook, their app is only in one of these architectures in the case of React Native, what uses several technologies are the micro services behind, there they can be distinct technologies but also are distinct applications. My question is how in a single Android app join all these cited technologies.
– Alisson Marqui
@Alissonmarqui understands your point of view and respect completely. The Facebook I quoted is just one example. What I wanted to show is that an app the size of Facebook can not be recreated from scratch whenever the market requests. Formerly apps were just native, then came webview-based apps and now came these exciting technologies like React Native and Flutter... Facebook existed in most of this period of evolution and had to adapt. That’s why I defend the gradual evolution, in case it would be inserting little by little the "new" until the app is complete.
– Leonardo Paim
At first it seems like a scam, but it’s something normal in this area where frameworks are used to compile for various platforms. Imagine that you have several classes of your app written in Java and want to migrate only the "visual" part to Flutter, because of the ease of development. You don’t need to rewrite your entire application with Dart, you can use a "channel of communication Feature" Flutter and call Java classes/methods through Dart easily.
– Renan Gomes