You Don’t Need a Rewrite, You Need React Native Brownfield

So we want you to keep as much code as possible operational so that you can move even faster.
Even in green field apps, you have some amount of native code, some amount of native logic that's running your React Native app.
But in brownfield apps, you actually have an actively developed native app.
You might have Swift UI screen, Swift screens, Cotlin, Jetack compos screens, and then you add React Native screens on top of those existing stacks.
In green field apps, React Native owns the app, but in brownfield it might be the vice versa.
There are multiple things to consider when you are doing brownfield because greenfield is essentially brownfield but with just one screen where react native takes over.
In order to do brownfield in the olden days, you'd have to, let's say, I don't know, copy React Native repository, get some files from there, move them to your project, remember which versions you copied them from, and then modify it.
So, a lot of native knowledge needed, and not only native, but like native React Native knowledge needed.
And then you'd have to maintain that custom implementation which each new version of React Native that you want to pull into your like I don't know packet JSON or something.
Yeah, I think it's just a lot of effort.
You would need like a master's degree in React Native and native development in general or you'd need to hire Colstack which is the total software engineering consultancy that does this podcast.
I'm a terrible host of this podcast.
Sorry for that.
Uh I promise not to do any more digressions.
[Music] React Universe on Air, your go-to podcast for all things crossplatform.
Hey everyone, this is Wukash and you already know the podcast you're listening to.
This is a a coffee talk edition.
Today we're talking about
And to do that I have two wonderful guests, my colleagues from Colstack, Burak and Oscar.
Can you guys please introduce yourself?
All right.
So, uh, my name is Oscar Kashnski.
I'm a senior software engineer here at Col.
I'm doing like all sorts of open-source things around here.
Uh, and yeah, that's that's pretty much it.
And I'm Barack.
I will call myself a brownfield enthusiast.
And that's it.
Okay, that was pretty short for me.
You guys have uh really great job at Colstack working with open source uh bringing the tools to the community, working on the tools and not working for the clients because working for the clients, you know, uh sometimes hard.
Uh I'm not saying that open source is not hard.
Sorry for that.
Let's Okay, before before they fire me, let's go back to the episode.
So, we're talking about Brownfield today and we already had two different episodes of uh back then uh React the React Native Show podcast about Brownfield.
So, if you want to know some ground rules, we will explain them as well, but if you want to know some more ground rules, go back to episode 6 with Mike Gravski and Mike Hujak and to episode 13 with me and Mike Hujak as well.
And in in that episodes we were explaining the origin of the term green field brownfield.
So maybe let's not explain it anymore on this podcast.
What I want to ask you guys about is what is the craziest setup for brownfield in React Native that you've seen in real world.
So the craziest um setup that I can think of is if you have native apps, you probably also have some complicated custom setup that you want to keep and as a result that also complicates the brownfield integration.
So one example in this case is you can imagine you have all those third party SDKs like
So if you're an iOS dev, you are probably familiar with those XC framework files or Swift package manager packages.
So what happens when you try to integrate React Native into this setup with already existing third party frameworks.
So in this case we have a couple of options and one of those is we get all those framework files those third party frameworks like the Firebase framework and then we try to also make it work with React Native's Firebase SDK.
So there's a package called React Native Firebase and there's a hack that makes it possible for that React Native package to use the third party framework that you already have so that you don't have to keep that the same framework bundle twice in the app.
You can share because usually when you get React Native Firebase you install it uh as a React Native dependency that brings its own native dependencies.
Exactly.
So it brings its own on iOS it brings its own.
exe XC framework file and that file is a library with native code.
So is that approach that you said it's a hack?
Is that approach like transferable to other libraries that have native uh parts as well?
Kind of.
Okay.
How what about um what about the compatibility uh between that?
So that's always a problem, right?
Because you don't want to get vendor locked because of React Natives versions.
And in this case like the React Native Firebase was uh behind in Firebase versions.
So like you might have to adjust your own version just in case.
Cool.
So right from the start we we dive deep into the technicals.
Uh I asked maybe uh too complicated question.
I expected maybe some more uh short answer.
I can give you a simpler answer like what I saw.
So uh once there was uh
It was actually a like a braford app made by meta uh where one tab was the old architecture and the second tab was the new architecture and they compared uh like old to new one.
But uh this would work uh mostly only with React Native because there are some uh most of the package creators actually uh have some if defs around the new and old architecture.
So if you try to run your app in like one tab with new architecture in the the second tab with old architecture, it wouldn't work with third party dependencies.
But you can you know uh test for example your library like this if you would like to like test new and old architecture um in the same time because this for library maintainers this is a pain because you have to rebuild the app constantly and check so so yeah this is one of the uh examples I saw I I don't think that it's like practical to do that in this case like I cannot imagine why would anyone want to do that in the aperture But in the library, it's like in the library desktop.
I mean, it's it's a good option.
Like I've tried that.
It worked, but then I wrote back to the default version.
Um, so yeah, you should probably shouldn't do that uh in your app, but it's good to know there are possibilities like this where you can like really shape React Native uh to work however you need it to work.
Yeah.
cuz like usually going brownfield is more like web developer uh job.
You you usually don't want to mess with native files etc etc.
But brownfield is a whole different animal where by default you need to deal with uh native dependencies or do you I don't know maybe this new version of real native brownfield uh deals with it for you.
So I said go back to those two episodes to to learn the
It would have its own main activity as long as you're not using expo.
But even if you're using expo that all those stuff are handled for you in the um in the background, meaning the like meaning like the shell native app that runs your React Native engine, let's say.
Yeah.
So like you have to have at least some amount of native code that's running your React Native bundle, loading everything and just like letting it run.
it hands over the ownership of the application to the React Native bundle with a Greenfield app.
So even in green field apps, you have some amount of native code, some amount of native logic that's running your React Native app.
But in brownfield apps, you actually have an actively developed native app.
You have you might have Swift UI screens, Swift screens, cop colon, jetack compos screens, and then you add React Native screens on top of those existing stacks.
You can have separate navigation stacks that handle react native navigation and all this kind of stuff.
So the main difference is in green field apps react native owns the app but in brownfield it might be the vice versa.
Yeah.
So like there is also this case uh where you because in green field you get to the app did finish launching with options.
This is the method on the native side that gets called whenever your app finishes launching and then react native gets
So it fills the screen.
But in green field uh there may be a case where for example your main screen is native like it's built with UI kit but then you get to the for example settings page that's built in react native and only then you want to initialize react native or where for example user is approaching this tab like you may have some custom logic where you want to like uh initialize start yeah pre react native start initializing it in the background and and uh create the view uh whenever user actually hits that tab because he may never uh enter the settings.
So uh there are multiple things to consider when you are doing brownfield because green field is is essentially brownfield but with just one uh one screen where react native takes over.
So yeah that's that's essentially the the main difference.
Yeah, it's uh when Burak was talking about u that this is a shell app and it requires some native code.
Actually, there is a bunch of native code there.
Like that's that's the whole app, right?
We we don't see that code as React Native developers.
We mostly don't see that code as native developers as well because like we care about only like our entry points and then we build our own files.
But it's there.
And I wonder if you start a new green field app and you push it to GitHub, what's the percentage of like JavaScript versus Swift versus Java versus Cotlin, etc.
Right?
Like what's the percentage of lines of code that are actually native?
I would say like you have your app delegate in Swift and that's all the Swift code apart from maybe like main.
M the objective C file.
So like only a couple of files on iOS and only a couple of files on Android.
I don't think that it's so like obviously the percentage depends on how much
Yeah.
So I got the data.
I've checked it.
Uh it's for React Native.
Oh, let's say uh 79.
It's so I'm checking this on the React Native community template.
how much the template actually has uh JavaScript, cotlin and all sorts of things.
So it has 56% of JavaScript uh 13% of cotlin and now 7% of swift no objective C uh and 9% of Rabi which is like mostly for cocoaots uh configuration and now it's also 5% of TypeScript.
So I think the 56% of JavaScript comes from actually some scripts that they have in the community template.
So like they have some scripts to release it.
Uh so yeah this the the amount of native code is is not that big.
Most of the native code for uh React Native actually sits in React Native uh package.
That actually blew out my assumption.
My assumption was that when you create a fresh project, the the native files will have much bigger share of the actual code base.
Thank you.
And uh for everyone listening, we didn't prepare this question beforehand and Oscar actually find that out in like 15 seconds.
So, congrats Oscar.
You're great at Googling.
Already got a native app and you don't want to rebuild it from scratch?
You can layer React Native on top and start taking advantage of crossplatform features right away.
If you're not sure how to start or just want to talk it through, reach out to us at Colstack.
We've done this plenty of times and we're happy to help.
We covered green field, brownfield, like what is actually happening in those approaches like on the high level.
So let's maybe go lower to lower level and talk about how historically we were doing
So yeah, in the like historically uh you would need to basically copy everything from I'm going to talk about iOS because that's mostly what I'm now what I'm mostly familiar with but the approach was similar to Android.
So let's talk like more high level but for iOS.
Borak you can fill in on Android if you uh if you want to.
So you got us too and we both expertise on iOS not Android.
Yeah.
Yeah, that's true.
Um, so like on iOS there is this RCT app delegate which is a class that you subclass for your like main entry point of the app.
So the app delegate is the entry point for your iOS app and this is where the like did finish launch of options function gets called um as I said before.
So there was this abstraction React Native RCT delegate that inside of it had all of the um implementation details of how to uh initialize React Native.
So you had like your uh creation of the bridge and then later on with the new architecture creation of the uh RCD instance and all sorts of things like that.
It was I had a presentation like last year on some conference showing the actual amount of code and it didn't feel on the one uh slide so it was like scrolling.
So you had to copy all of this from React Native to your project to have brownfield working.
Uh and then when like for example I don't know react 72 or 73 came out you had to update uh everything to account for this new version and like switching to new architecture and architecture also wasn't that easy because you also had to maintain this code for switching.
So yeah this is this was a pain for sure like working on on this uh old architecture new architecture stuff.
So you had to basically always uh subclass this app delegate uh in your app and this wasn't ideal for like integration to native projects because you may want
If I can try to dumb it down a little bit for my own sake.
In order to do brownfield in the olden days, you'd have to, let's say, I don't know, copy React Native Repository, get some files from there, move them to your project, remember which versions you copied them from, and then modify it.
So, a lot of native knowledge needed.
and not only native but like native React Native knowledge needed and then you'd have to maintain that custom implementation which each new version of React Native that you want to pull into your like I don't know packet JSON or something.
Yeah, I think it's just a lot of effort.
you would need like a master's degree in React Native and native development in general or you'd need to hire Colstack which is the total software engineering consultancy that does this podcast.
Yeah.
And on top of that uh the whole whole code in React Native was in Objective C.
So like if you wanted to integrate it with Swift, you had to also translate it to Swift.
And like it doesn't work that well with in Swift because it uses C++ under the hood.
So yeah, it it wasn't easy.
You had to like create wrappers around Objective C.
So you don't expose C++ in headers to Swift because then Swift like blows up and it doesn't work.
So yeah, this this was a nightmare and I'm happy that it's over.
As far as I know, that's like the way that let's say custom brownfield integration worked.
But we have had this uh react native brownfield app at Colstack for years now.
So what's up with that package?
How how that package back in the days helped me out with all of that that you just described?
That's
And the second question, how that package evolved and why are we talking about it right now?
Back in the day, there was this issue as I described.
Let's uh focus only on our architecture because like new architecture wasn't a thing uh for couple versions behind before uh this package was mostly doing this thing.
So it encapsulated the whole logic of creating this new um RCT root view.
it was called before which is just a UI view on iOS that you can use for example to implement this settings screen in your app.
So uh react native profit allow you to had an easy way to initialize React Native.
So to create the everything uh that you needed so the bridge and all sorts of things like that.
So you could call one function that would initialize like setup react native and then call another function that uh when you needed a new view it would create it for you.
So you would just display it in your uh UI as as a normal uh UI view.
So basically an like quality of development utility library and it also like help you uh with um the navigation.
So for example whenever you have like native navigation you navigate to React Native.
Let's say you do a push uh to to navigate to to to React Native.
Then inside of React Native, you also have your native stack.
So you push new screens and whenever you get to like the the first screen, so users goes back goes back then it's on the last screen of React Native and wants to go back to native.
This is this is an issue.
So uh React Native run exposed a method that you can call which was called pop to native and you can then go back from React Native back to native.
So you could like seamlessly um transition between native and react native.
I imagine like going off topic from React Native brownfield a little bit into like
I imagine this barrier between native and react native like that's the like most tricky part to deal with not only in this example in navigation but like uh across the board right like the barrier is the is the tricky part I think when you have two systems that has to talk to each other that's like the trickiest part like you can also think about backend and front end communication like you had all those API layers that are trying to like um go odd over the years because people now understand that this is the uh biggest barrier um for development.
So they are trying to unify backends and front ends like a lot of approaches with react server components and everything.
So you might also think about react native and I would say like native versus JavaScript code you have to communicate and I think that's the trickiest part with the brownfield approach.
Okay, sorry Oscar for interrupting you.
Uh back to our episode about React Native brownfield.
Yeah.
So okay um only for old architecture.
So this is important because it didn't work for new architecture.
Now it works.
Uh but in order to get uh React Native profit to the state that it is today, we had to implement couple of things inside of React Native core.
So like the whole backstory uh behind how this changes happened inside of React Native is that we worked on React Native Vision OS uh which uh requires us to use Swift UI.
So uh in order to use Swift UI uh in React Native you had to basically rewrite the whole flow of how you initialize the like React Native in your app.
So basically we had to write react native like brownfield for swift UI uh inside of the inside of the project.
So I wrote this uh in order for people to like use react native vision west because it was the only way there to create native
You can also have multiple screens in there.
So that's that's a bit uh complex.
So uh I was working on React Native Vision West and there was a need for me to unify how uh React Native works because every time there was a new release, I had to change everything and as I told you this was the pattern before.
Uh but I had to change it for new architecture and old architecture.
So I started to work uh with Ricardo uh from the core team at Meta and we came up with this API which was called uh which is called is to uh use RCT root view factory.
So this API like encapsulates uh creation of the new view and at the time I I was thinking like this is this is perfect like this is all we need.
We just use RT factory.
So this was like a pretty big PR I've created to to React Native.
I worked on it for a while.
It got merged and suddenly like after a few releases, you had to still use the RCT uh app delegate.
So it wasn't the solution like people from Meta started to add things inside of the app delegate.
They didn't add to the root view factory.
So, it was kind of getting out of sync with with like how I wanted it to work like.
So, um yeah, it kind of worked, but you still had to do some manual steps in order to get the Ruby factory working.
So, then I sat down once again and created React Native Factory.
So there are a lot of factories but um react native factory it's like its main goal was to like completely remove the RCD delegate thing which is subclass.
So now uh you don't need to subclass anything you just create a new root view factory and from that root view factory like it encapsulates the creation of a react
So it set up sets up the react instance and stuff like that and for it also has the logic for setting up old architecture and new architecture.
So once you create the react native factory, you can then use the previously mentioned root view factory which allows you to create the views and this will be the final factory, right?
Yeah, this is the final factory.
No more factories.
Um, so yeah, this was a long road like it took a while to implement this.
It was like a I was refactoring the whole uh React Native initialization.
So inside of React Native while you know everyone was still contributing uh to React Native.
So the the PR was constantly getting out of sync and like had conflicts but after like few months I would say uh we managed to merge it and now in React 79 uh the RCD update is finally uh deprecated.
So it's like the transition period.
Now you can use the React native uh factory like without the uh RCT delegate.
And in the newer versions, we will like completely migrate off HCT app delegate and uh set up the uh React Native inside of your app delegate like in the template which will make kind of React Native be brownfield first because um then you can just look at the template and copy whatever is there and initialize it in your native app.
So there will be no longer some abstractions that you need to subclass which is not ideal in this uh brow field scenario because some people may already have some subasses in your app delegates or whatever that they don't use app delegate they prefer scene delegates.
So yeah this was this was a long uh way from uh visual OS now to uh react 080 which will have this uh enabled.
I really tried.
Thank you.
Thank you for this.
Uh it was really deep and I really tried not to interrupt and get you off
I have three notes that I needed to write write down before I forget them.
React Native Factory.
Great name for React Native Software House or something.
React native fac if if you start react native factory software house I get the I don't know what's that what's that called like uh percentage of your of your gains or something.
So second topic that I have noted down uh again shameless plug we did episodes with Oscar about React Native Vision OS about a year and a half ago and back then he was talking about those factories not not all of them but the changes that he had to make to a bunch of different repositories React Native included React Native core included to make it more like pluggable to make it more pluggable for other platforms, for new platforms.
So that's part of that effort and what you just explained to us is that after that missing piece for vision OS there were still needs to like generalize it to generalize react native architecture to be even more like extensible uh for not only other platforms but also for like different kinds of projects.
So those changes that you just described were to the core repo and not really we haven't really been talking about React Native brownfield changes.
So uh let's get to that maybe.
Sure.
Um so yeah this was the foundation we needed to lay for React Native profit to be great again to be back.
So uh now that we have like all these APIs inside of React Native and we have meta maintaining them so they're keeping them up to date whenever something changes I don't know they add some new new thing to react native we don't have to add it in react native brownfield and yeah uh you can you can just use them from uh from react native b maybe you want to because I've been talking about a lot so you can so I
This podcast is one big advertisement for our blogs, for our podcasts, for our open source work.
I don't know like yeah sorry that that's a joke.
Uh go check out the article definitely we will link link it in the show notes.
Yeah, we have all these new features with React Native brownfield that are awesome.
So to sum it up, um you would previously need to create UI kit, Swift UI, Android views manually yourself by calling React Native internals.
Now we have some viewer APIs that can load SwiftUI views, UI kit ones, jetack compos views, all of them handled for you.
So you don't have to use those React Native, I would say internal, but they're not internal APIs.
So you wouldn't need to use those API that might be a bit too low level for you.
You can just use React Native Braumfield.
It has a native facing interface.
So it's not a JavaScript only package.
You can import and use it from um Swift and Cotlin code.
So you can just use those APIs to create those views, those React Native VS um using the package instead of doing everything yourself.
on top of that like we have this um approach of packaging react
You got an iOS folder with a project, an Xcode project.
You got an Android folder that has a build.
gradal file inside it.
And then you have you probably have an SRC file with TypeScript, JavaScript flow code that you have.
That's the standard template, I guess.
So, yeah, this is a standard template.
And you can do this approach with the brownfield apps.
But you might guess that this would require you to get all your native apps in a single repository.
And that's not good news for everyone because you might have some specific CI jobs.
You might have some pull request.
I don't know.
So you have to like change all the way that you work.
You you have to change all the repos that you have to add React Native.
And obviously we don't want that.
We don't want you to disrupt your whole work just to use React Native.
So that was the kind of legacy approach with brownfield apps.
So the second way to do this is you might have guessed like normally when you have libraries like let's say JavaScript libraries you normally upload them to MPM so that it can be uh consumed by other repositories let's say and in this case what we do is iOS has this native packaging format called frameworks andexe frameworks and Android has a files so you can think of these as um you have npm packages and you have package um tar files you can Think about those native files as those tar files.
So what we do is we take all
So those framework files have everything packaged for you.
So you can just add it to your native application and then just use React Native.
That's it.
You don't have to install coile pods, anything else on your native apps just to use React Native because we know that you don't want to see pod file in your native app that uses Swift package manager.
It's not elegant.
So, um we just package everything from one React Native repo that you don't even have to like look at it.
You don't even have to know that it exists.
It just exists and sends packages to you and you as a native dev can just consume it and use it.
You're listening to React Universe on Air, your go-to podcast for all things crossplatform with React and React Native.
from talking with Mike Hujak, I don't know, it was like three years ago or something on that episode 13.
Um, he stressed that it's really important for brownfield project that want to integrate React Native in let's say big enterprises or something is that we like you said we don't disrupt the flow of existing developers.
If we have an app that has like I don't know hundreds of native screens already and we want to enable React Native for people that want to use it but then we don't want to interrupt everyone's workflow.
We don't want them to build React Native or Start Metro or anything like crazy like that.
They should be able to work with their app as they are used to.
And we are just adding on top of that another library, another utility that just allows you to do React Native.
So I guess like one way that I like to think about those React
And the reason is you normally have web views, they use they might use reactive and you have a special communication pattern with web views.
You have to like use some window.
event listeners to just like communicate with them.
And you kind of have the same approach with all the React Natives do except React Native can also have its own native stack and it's fully native.
So you can also use native APIs.
You don't have to write custom code just to delegate all those native calls.
Talking about native and React Native and that like integration layer between uh communication layer.
Uh let's go back to that um boundary that we discussed and let's let's maybe talk about what can we share, what should we share, what can't we share between the two words.
So that's a great question and my answer is as always it depends.
It depends on your use cases.
So it's always costy to send data between two systems because you have your native swift types, you have your native cotlin types, objective C types, and you want to convert them to JavaScript types somehow.
There are a couple of ways to do that.
You can use JSON, you can use JSI for direct access.
I'm not going to go into detail, but this always comes with a cost.
So it's not free.
So it's always a pros and cons of sending data between platforms.
I would say if you want the absolute best performance, it's always better to send as little as data as possible.
Let's say I have a like I have an app, I have my up state, my global app state.
I have like different screens written in different technologies, but I still want them to share the same data, to have the same user logged in, to have like the same products in the in the shop cart or or something like that.
So like what's
I guess now we are on a different realm because previously we were talking about sending data from native to JavaScript layer but now we have JavaScript to JavaScript communication and good news is that JavaScript share the same context and I guess like Oscar can explain it much better than me because he's been working with all those internals bridge.
I wanted to add to the uh before like passing data because uh you can always pass initial props from native to react native and this is probably the easiest way that you can pass data.
So it kind of works like I don't know server components kind of like you pass some initial data and you receive it in props.
So yeah, I wanted to add to this to the previous uh thing we were talking about that this is probably the simplest and the fastest way you can pass something down.
uh Burak uh please explain what we can do about like sharing the state across because this is a tricky tricky topic and I think like maybe like my question my question comes from my like general understanding of the apps like probably like the biggest thing that you want to share between those two realms is like your app state right?
Yeah, definitely.
So like um I would say at least you have to share some user token or something like that to show that you you have logged in.
Um I don't know if you are doing whole navigation stacks, you might also want to like pass some props but I think the best are and when I say best is arguably the best but I think it's always better to have less side effects in your code.
So one way that I like to think about those react native brownfield modules is if you can keep those uh side effects as minimal as possible and when I say side effects it's something like oh I have a native app call that changes everything
So the answer is yes.
And the reason why the answer is yes is because when you initialize a bridge instance it this was the old architecture and I think we have some similar API on new architecture as well.
It generates a single JavaScript context for you.
So if you have a couple of React Native screens that you use in your native applications.
I don't know maybe like you have a native screen that consumes two screens that are half sized each.
So they can communicate between each other using some sort of client state management library such as BDAX thanks to them being hosted in a single JavaScript memory.
So they will know
So say we go back to the example from Oscar that our settings screen is in react native and then I have completely different screen like in completely different part of the app.
Those two screens by default share the same JavaScript context.
They can talk with each other.
How about and this this will be another digression.
I'm sorry.
How about if I want to use like different React Native versions for those different screens?
Can I create two different contexts?
Now you have some technical depth because probably not.
The native code is the same but you can have v like react native factory.
It is a factory to create react native new instances.
So you can technically have two react native instances and two separate um hermes instances for you to have two JavaScript contexts.
And we actually uh used it on client project once uh for a PC so that you could have like a safe uh environment to execute JavaScript.
So you have one instance for React Native and we create a new instance which is totally separate JavaScript instance totally separate Hermes and like React Native to have a safe environment to execute uh JavaScript separately from your main app.
So the use case is to force those two separate contexts so that they don't share uh anything between them.
The main goal was for AI to have a safe context to execute something uh so that it doesn't like you know create some side effects.
Yeah.
So it doesn't like inject something into global that can affect your main app.
It has a separate global.
So uh that was the main main goal to have a safe environment for AI to generate code.
That was our main uh idea.
But you can also use this for example for um mini apps where you have
But that also comes with its own overhead, right?
It's not like Yeah, it's not free.
Yeah, it's it's definitely you have to create a separate React Native instance which is a cost in itself.
Yeah, go by memory.
You've been talking about like cost in terms of like memory management, processing power management or something like that.
I also think about the cost of complexity and cost of like dealing with this kind of repository.
Then we already have a brownfield integration.
Now we have to think about all of those other layers of complexity.
probably like the best practice approach would be to keep the complexity as minimal as possible because we already are adding a lot of complexity like it's always a trade-off between like developer productivity debugging time and complexity.
So I guess like if you can keep the dependencies as minimal as possible it's the best as it can get.
That's why like I was talking about having code that is side effect free so that doesn't have a lot of dependencies between realms.
Okay, looking at my notes, I think we went over a bunch of things from like React Native brownfield.
Is there any anything that we missed that you want people to know about like using this this technology?
So I guess like one thing that I would like to add is this yeah like today's it's this might still require some some sort of expertise in at least some native code in React Native.
So it might be a um like huge stopper for some teams to adopt this technology but it's getting easier and easier and we are working on this area to improve it.
So uh maybe like today you're not able to find a lot of resources but I would say
It's it's it has huge potential because rewriting sucks.
So we we want you to keep as much as code as possible operational so that you can move even faster.
I'm thinking what what Oscar said about like adding all of those generalizations to React Native.
I'm thinking React Native has matured so much in this like green field approach that the like the obvious way for us to grow for our technology to grow is to incorporate the brown field and to embrace the brown field because this will open up for us new possibilities and I think the market of crossplatform is going that direction as well.
So uh linksjs this new framework from bite dance I think it's brownfield first and it allows not only react but it allows a bunch of different like framework technologies.
I think brownfield is the next front frontier for us.
uh new platforms are also like uh a way for us to grow and it's exciting to see so much so much movement in in our crossplatform space not only in react native but like I like I mentioned linksjs we can borrow and like learn from each other a lot I think in that regard what do you guys think yeah definitely I think like this is a great point to um compete with react native for links because if you have a technology that's called links and you want people to use it, you cannot just be like, oh, like now you just have this and create a new app.
No, that create a new app is what I think what's what's stopping people from trying these new technologies.
I think it's the best that we let them use it as they want so that they don't have to create a new app.
They can just use their own code.
I agree 100%.
And have nothing to add.
Yeah, maybe guys you can tell us the last thing is to where can people find you?
Where is this React Native brownfield library docs, podcasts, etc.
?
Yeah, so it's on our GitHub uh on the call stack, github.
com/call stack.
Uh you can find the react native battlefield.
I think if you type into Google React Native profit, this is the first thing that pops up.
So um check it out.
Uh you can find me on Twitter and GitHub.
I'm there uh under the handle o kashnvki.
I just searched Oscar Kashnvki in Google and your website is the first result for me.
So you're easily googleable.
You're not going to be able to find me.
No, my name is so generic.
Okay.
And you can find me at ax_atlj.
Okay.
We will link all of your profiles and all of the links in the show notes.
And if you want to follow Colag, we are easily findable on the web.
Just follow us on everything.
We started releasing those episode on Twitter on X as well.
So you can watch us there.
Uh let us know how you like this episode.
We are waiting for your comments.
And thank you guys so much for joining me.
I had a blast this morning with my coffee and my Red Bull.
And see you somewhere in the near future.
See you.
See you.
Thank you.
See you.
Heat.
Heat.
[Music]


So we want you to keep as much code as possible operational so that you can move even faster.
Even in green field apps, you have some amount of native code, some amount of native logic that's running your React Native app.
But in brownfield apps, you actually have an actively developed native app.
You might have Swift UI screen, Swift screens, Cotlin, Jetack compos screens, and then you add React Native screens on top of those existing stacks.
In green field apps, React Native owns the app, but in brownfield it might be the vice versa.
There are multiple things to consider when you are doing brownfield because greenfield is essentially brownfield but with just one screen where react native takes over.
In order to do brownfield in the olden days, you'd have to, let's say, I don't know, copy React Native repository, get some files from there, move them to your project, remember which versions you copied them from, and then modify it.
So, a lot of native knowledge needed, and not only native, but like native React Native knowledge needed.
And then you'd have to maintain that custom implementation which each new version of React Native that you want to pull into your like I don't know packet JSON or something.
Yeah, I think it's just a lot of effort.
You would need like a master's degree in React Native and native development in general or you'd need to hire Colstack which is the total software engineering consultancy that does this podcast.
I'm a terrible host of this podcast.
Sorry for that.
Uh I promise not to do any more digressions.
[Music] React Universe on Air, your go-to podcast for all things crossplatform.
Hey everyone, this is Wukash and you already know the podcast you're listening to.
This is a a coffee talk edition.
Today we're talking about
And to do that I have two wonderful guests, my colleagues from Colstack, Burak and Oscar.
Can you guys please introduce yourself?
All right.
So, uh, my name is Oscar Kashnski.
I'm a senior software engineer here at Col.
I'm doing like all sorts of open-source things around here.
Uh, and yeah, that's that's pretty much it.
And I'm Barack.
I will call myself a brownfield enthusiast.
And that's it.
Okay, that was pretty short for me.
You guys have uh really great job at Colstack working with open source uh bringing the tools to the community, working on the tools and not working for the clients because working for the clients, you know, uh sometimes hard.
Uh I'm not saying that open source is not hard.
Sorry for that.
Let's Okay, before before they fire me, let's go back to the episode.
So, we're talking about Brownfield today and we already had two different episodes of uh back then uh React the React Native Show podcast about Brownfield.
So, if you want to know some ground rules, we will explain them as well, but if you want to know some more ground rules, go back to episode 6 with Mike Gravski and Mike Hujak and to episode 13 with me and Mike Hujak as well.
And in in that episodes we were explaining the origin of the term green field brownfield.
So maybe let's not explain it anymore on this podcast.
What I want to ask you guys about is what is the craziest setup for brownfield in React Native that you've seen in real world.
So the craziest um setup that I can think of is if you have native apps, you probably also have some complicated custom setup that you want to keep and as a result that also complicates the brownfield integration.
So one example in this case is you can imagine you have all those third party SDKs like
So if you're an iOS dev, you are probably familiar with those XC framework files or Swift package manager packages.
So what happens when you try to integrate React Native into this setup with already existing third party frameworks.
So in this case we have a couple of options and one of those is we get all those framework files those third party frameworks like the Firebase framework and then we try to also make it work with React Native's Firebase SDK.
So there's a package called React Native Firebase and there's a hack that makes it possible for that React Native package to use the third party framework that you already have so that you don't have to keep that the same framework bundle twice in the app.
You can share because usually when you get React Native Firebase you install it uh as a React Native dependency that brings its own native dependencies.
Exactly.
So it brings its own on iOS it brings its own.
exe XC framework file and that file is a library with native code.
So is that approach that you said it's a hack?
Is that approach like transferable to other libraries that have native uh parts as well?
Kind of.
Okay.
How what about um what about the compatibility uh between that?
So that's always a problem, right?
Because you don't want to get vendor locked because of React Natives versions.
And in this case like the React Native Firebase was uh behind in Firebase versions.
So like you might have to adjust your own version just in case.
Cool.
So right from the start we we dive deep into the technicals.
Uh I asked maybe uh too complicated question.
I expected maybe some more uh short answer.
I can give you a simpler answer like what I saw.
So uh once there was uh
It was actually a like a braford app made by meta uh where one tab was the old architecture and the second tab was the new architecture and they compared uh like old to new one.
But uh this would work uh mostly only with React Native because there are some uh most of the package creators actually uh have some if defs around the new and old architecture.
So if you try to run your app in like one tab with new architecture in the the second tab with old architecture, it wouldn't work with third party dependencies.
But you can you know uh test for example your library like this if you would like to like test new and old architecture um in the same time because this for library maintainers this is a pain because you have to rebuild the app constantly and check so so yeah this is one of the uh examples I saw I I don't think that it's like practical to do that in this case like I cannot imagine why would anyone want to do that in the aperture But in the library, it's like in the library desktop.
I mean, it's it's a good option.
Like I've tried that.
It worked, but then I wrote back to the default version.
Um, so yeah, you should probably shouldn't do that uh in your app, but it's good to know there are possibilities like this where you can like really shape React Native uh to work however you need it to work.
Yeah.
cuz like usually going brownfield is more like web developer uh job.
You you usually don't want to mess with native files etc etc.
But brownfield is a whole different animal where by default you need to deal with uh native dependencies or do you I don't know maybe this new version of real native brownfield uh deals with it for you.
So I said go back to those two episodes to to learn the
It would have its own main activity as long as you're not using expo.
But even if you're using expo that all those stuff are handled for you in the um in the background, meaning the like meaning like the shell native app that runs your React Native engine, let's say.
Yeah.
So like you have to have at least some amount of native code that's running your React Native bundle, loading everything and just like letting it run.
it hands over the ownership of the application to the React Native bundle with a Greenfield app.
So even in green field apps, you have some amount of native code, some amount of native logic that's running your React Native app.
But in brownfield apps, you actually have an actively developed native app.
You have you might have Swift UI screens, Swift screens, cop colon, jetack compos screens, and then you add React Native screens on top of those existing stacks.
You can have separate navigation stacks that handle react native navigation and all this kind of stuff.
So the main difference is in green field apps react native owns the app but in brownfield it might be the vice versa.
Yeah.
So like there is also this case uh where you because in green field you get to the app did finish launching with options.
This is the method on the native side that gets called whenever your app finishes launching and then react native gets
So it fills the screen.
But in green field uh there may be a case where for example your main screen is native like it's built with UI kit but then you get to the for example settings page that's built in react native and only then you want to initialize react native or where for example user is approaching this tab like you may have some custom logic where you want to like uh initialize start yeah pre react native start initializing it in the background and and uh create the view uh whenever user actually hits that tab because he may never uh enter the settings.
So uh there are multiple things to consider when you are doing brownfield because green field is is essentially brownfield but with just one uh one screen where react native takes over.
So yeah that's that's essentially the the main difference.
Yeah, it's uh when Burak was talking about u that this is a shell app and it requires some native code.
Actually, there is a bunch of native code there.
Like that's that's the whole app, right?
We we don't see that code as React Native developers.
We mostly don't see that code as native developers as well because like we care about only like our entry points and then we build our own files.
But it's there.
And I wonder if you start a new green field app and you push it to GitHub, what's the percentage of like JavaScript versus Swift versus Java versus Cotlin, etc.
Right?
Like what's the percentage of lines of code that are actually native?
I would say like you have your app delegate in Swift and that's all the Swift code apart from maybe like main.
M the objective C file.
So like only a couple of files on iOS and only a couple of files on Android.
I don't think that it's so like obviously the percentage depends on how much
Yeah.
So I got the data.
I've checked it.
Uh it's for React Native.
Oh, let's say uh 79.
It's so I'm checking this on the React Native community template.
how much the template actually has uh JavaScript, cotlin and all sorts of things.
So it has 56% of JavaScript uh 13% of cotlin and now 7% of swift no objective C uh and 9% of Rabi which is like mostly for cocoaots uh configuration and now it's also 5% of TypeScript.
So I think the 56% of JavaScript comes from actually some scripts that they have in the community template.
So like they have some scripts to release it.
Uh so yeah this the the amount of native code is is not that big.
Most of the native code for uh React Native actually sits in React Native uh package.
That actually blew out my assumption.
My assumption was that when you create a fresh project, the the native files will have much bigger share of the actual code base.
Thank you.
And uh for everyone listening, we didn't prepare this question beforehand and Oscar actually find that out in like 15 seconds.
So, congrats Oscar.
You're great at Googling.
Already got a native app and you don't want to rebuild it from scratch?
You can layer React Native on top and start taking advantage of crossplatform features right away.
If you're not sure how to start or just want to talk it through, reach out to us at Colstack.
We've done this plenty of times and we're happy to help.
We covered green field, brownfield, like what is actually happening in those approaches like on the high level.
So let's maybe go lower to lower level and talk about how historically we were doing
So yeah, in the like historically uh you would need to basically copy everything from I'm going to talk about iOS because that's mostly what I'm now what I'm mostly familiar with but the approach was similar to Android.
So let's talk like more high level but for iOS.
Borak you can fill in on Android if you uh if you want to.
So you got us too and we both expertise on iOS not Android.
Yeah.
Yeah, that's true.
Um, so like on iOS there is this RCT app delegate which is a class that you subclass for your like main entry point of the app.
So the app delegate is the entry point for your iOS app and this is where the like did finish launch of options function gets called um as I said before.
So there was this abstraction React Native RCT delegate that inside of it had all of the um implementation details of how to uh initialize React Native.
So you had like your uh creation of the bridge and then later on with the new architecture creation of the uh RCD instance and all sorts of things like that.
It was I had a presentation like last year on some conference showing the actual amount of code and it didn't feel on the one uh slide so it was like scrolling.
So you had to copy all of this from React Native to your project to have brownfield working.
Uh and then when like for example I don't know react 72 or 73 came out you had to update uh everything to account for this new version and like switching to new architecture and architecture also wasn't that easy because you also had to maintain this code for switching.
So yeah this is this was a pain for sure like working on on this uh old architecture new architecture stuff.
So you had to basically always uh subclass this app delegate uh in your app and this wasn't ideal for like integration to native projects because you may want
If I can try to dumb it down a little bit for my own sake.
In order to do brownfield in the olden days, you'd have to, let's say, I don't know, copy React Native Repository, get some files from there, move them to your project, remember which versions you copied them from, and then modify it.
So, a lot of native knowledge needed.
and not only native but like native React Native knowledge needed and then you'd have to maintain that custom implementation which each new version of React Native that you want to pull into your like I don't know packet JSON or something.
Yeah, I think it's just a lot of effort.
you would need like a master's degree in React Native and native development in general or you'd need to hire Colstack which is the total software engineering consultancy that does this podcast.
Yeah.
And on top of that uh the whole whole code in React Native was in Objective C.
So like if you wanted to integrate it with Swift, you had to also translate it to Swift.
And like it doesn't work that well with in Swift because it uses C++ under the hood.
So yeah, it it wasn't easy.
You had to like create wrappers around Objective C.
So you don't expose C++ in headers to Swift because then Swift like blows up and it doesn't work.
So yeah, this this was a nightmare and I'm happy that it's over.
As far as I know, that's like the way that let's say custom brownfield integration worked.
But we have had this uh react native brownfield app at Colstack for years now.
So what's up with that package?
How how that package back in the days helped me out with all of that that you just described?
That's
And the second question, how that package evolved and why are we talking about it right now?
Back in the day, there was this issue as I described.
Let's uh focus only on our architecture because like new architecture wasn't a thing uh for couple versions behind before uh this package was mostly doing this thing.
So it encapsulated the whole logic of creating this new um RCT root view.
it was called before which is just a UI view on iOS that you can use for example to implement this settings screen in your app.
So uh react native profit allow you to had an easy way to initialize React Native.
So to create the everything uh that you needed so the bridge and all sorts of things like that.
So you could call one function that would initialize like setup react native and then call another function that uh when you needed a new view it would create it for you.
So you would just display it in your uh UI as as a normal uh UI view.
So basically an like quality of development utility library and it also like help you uh with um the navigation.
So for example whenever you have like native navigation you navigate to React Native.
Let's say you do a push uh to to navigate to to to React Native.
Then inside of React Native, you also have your native stack.
So you push new screens and whenever you get to like the the first screen, so users goes back goes back then it's on the last screen of React Native and wants to go back to native.
This is this is an issue.
So uh React Native run exposed a method that you can call which was called pop to native and you can then go back from React Native back to native.
So you could like seamlessly um transition between native and react native.
I imagine like going off topic from React Native brownfield a little bit into like
I imagine this barrier between native and react native like that's the like most tricky part to deal with not only in this example in navigation but like uh across the board right like the barrier is the is the tricky part I think when you have two systems that has to talk to each other that's like the trickiest part like you can also think about backend and front end communication like you had all those API layers that are trying to like um go odd over the years because people now understand that this is the uh biggest barrier um for development.
So they are trying to unify backends and front ends like a lot of approaches with react server components and everything.
So you might also think about react native and I would say like native versus JavaScript code you have to communicate and I think that's the trickiest part with the brownfield approach.
Okay, sorry Oscar for interrupting you.
Uh back to our episode about React Native brownfield.
Yeah.
So okay um only for old architecture.
So this is important because it didn't work for new architecture.
Now it works.
Uh but in order to get uh React Native profit to the state that it is today, we had to implement couple of things inside of React Native core.
So like the whole backstory uh behind how this changes happened inside of React Native is that we worked on React Native Vision OS uh which uh requires us to use Swift UI.
So uh in order to use Swift UI uh in React Native you had to basically rewrite the whole flow of how you initialize the like React Native in your app.
So basically we had to write react native like brownfield for swift UI uh inside of the inside of the project.
So I wrote this uh in order for people to like use react native vision west because it was the only way there to create native
You can also have multiple screens in there.
So that's that's a bit uh complex.
So uh I was working on React Native Vision West and there was a need for me to unify how uh React Native works because every time there was a new release, I had to change everything and as I told you this was the pattern before.
Uh but I had to change it for new architecture and old architecture.
So I started to work uh with Ricardo uh from the core team at Meta and we came up with this API which was called uh which is called is to uh use RCT root view factory.
So this API like encapsulates uh creation of the new view and at the time I I was thinking like this is this is perfect like this is all we need.
We just use RT factory.
So this was like a pretty big PR I've created to to React Native.
I worked on it for a while.
It got merged and suddenly like after a few releases, you had to still use the RCT uh app delegate.
So it wasn't the solution like people from Meta started to add things inside of the app delegate.
They didn't add to the root view factory.
So, it was kind of getting out of sync with with like how I wanted it to work like.
So, um yeah, it kind of worked, but you still had to do some manual steps in order to get the Ruby factory working.
So, then I sat down once again and created React Native Factory.
So there are a lot of factories but um react native factory it's like its main goal was to like completely remove the RCD delegate thing which is subclass.
So now uh you don't need to subclass anything you just create a new root view factory and from that root view factory like it encapsulates the creation of a react
So it set up sets up the react instance and stuff like that and for it also has the logic for setting up old architecture and new architecture.
So once you create the react native factory, you can then use the previously mentioned root view factory which allows you to create the views and this will be the final factory, right?
Yeah, this is the final factory.
No more factories.
Um, so yeah, this was a long road like it took a while to implement this.
It was like a I was refactoring the whole uh React Native initialization.
So inside of React Native while you know everyone was still contributing uh to React Native.
So the the PR was constantly getting out of sync and like had conflicts but after like few months I would say uh we managed to merge it and now in React 79 uh the RCD update is finally uh deprecated.
So it's like the transition period.
Now you can use the React native uh factory like without the uh RCT delegate.
And in the newer versions, we will like completely migrate off HCT app delegate and uh set up the uh React Native inside of your app delegate like in the template which will make kind of React Native be brownfield first because um then you can just look at the template and copy whatever is there and initialize it in your native app.
So there will be no longer some abstractions that you need to subclass which is not ideal in this uh brow field scenario because some people may already have some subasses in your app delegates or whatever that they don't use app delegate they prefer scene delegates.
So yeah this was this was a long uh way from uh visual OS now to uh react 080 which will have this uh enabled.
I really tried.
Thank you.
Thank you for this.
Uh it was really deep and I really tried not to interrupt and get you off
I have three notes that I needed to write write down before I forget them.
React Native Factory.
Great name for React Native Software House or something.
React native fac if if you start react native factory software house I get the I don't know what's that what's that called like uh percentage of your of your gains or something.
So second topic that I have noted down uh again shameless plug we did episodes with Oscar about React Native Vision OS about a year and a half ago and back then he was talking about those factories not not all of them but the changes that he had to make to a bunch of different repositories React Native included React Native core included to make it more like pluggable to make it more pluggable for other platforms, for new platforms.
So that's part of that effort and what you just explained to us is that after that missing piece for vision OS there were still needs to like generalize it to generalize react native architecture to be even more like extensible uh for not only other platforms but also for like different kinds of projects.
So those changes that you just described were to the core repo and not really we haven't really been talking about React Native brownfield changes.
So uh let's get to that maybe.
Sure.
Um so yeah this was the foundation we needed to lay for React Native profit to be great again to be back.
So uh now that we have like all these APIs inside of React Native and we have meta maintaining them so they're keeping them up to date whenever something changes I don't know they add some new new thing to react native we don't have to add it in react native brownfield and yeah uh you can you can just use them from uh from react native b maybe you want to because I've been talking about a lot so you can so I
This podcast is one big advertisement for our blogs, for our podcasts, for our open source work.
I don't know like yeah sorry that that's a joke.
Uh go check out the article definitely we will link link it in the show notes.
Yeah, we have all these new features with React Native brownfield that are awesome.
So to sum it up, um you would previously need to create UI kit, Swift UI, Android views manually yourself by calling React Native internals.
Now we have some viewer APIs that can load SwiftUI views, UI kit ones, jetack compos views, all of them handled for you.
So you don't have to use those React Native, I would say internal, but they're not internal APIs.
So you wouldn't need to use those API that might be a bit too low level for you.
You can just use React Native Braumfield.
It has a native facing interface.
So it's not a JavaScript only package.
You can import and use it from um Swift and Cotlin code.
So you can just use those APIs to create those views, those React Native VS um using the package instead of doing everything yourself.
on top of that like we have this um approach of packaging react
You got an iOS folder with a project, an Xcode project.
You got an Android folder that has a build.
gradal file inside it.
And then you have you probably have an SRC file with TypeScript, JavaScript flow code that you have.
That's the standard template, I guess.
So, yeah, this is a standard template.
And you can do this approach with the brownfield apps.
But you might guess that this would require you to get all your native apps in a single repository.
And that's not good news for everyone because you might have some specific CI jobs.
You might have some pull request.
I don't know.
So you have to like change all the way that you work.
You you have to change all the repos that you have to add React Native.
And obviously we don't want that.
We don't want you to disrupt your whole work just to use React Native.
So that was the kind of legacy approach with brownfield apps.
So the second way to do this is you might have guessed like normally when you have libraries like let's say JavaScript libraries you normally upload them to MPM so that it can be uh consumed by other repositories let's say and in this case what we do is iOS has this native packaging format called frameworks andexe frameworks and Android has a files so you can think of these as um you have npm packages and you have package um tar files you can Think about those native files as those tar files.
So what we do is we take all
So those framework files have everything packaged for you.
So you can just add it to your native application and then just use React Native.
That's it.
You don't have to install coile pods, anything else on your native apps just to use React Native because we know that you don't want to see pod file in your native app that uses Swift package manager.
It's not elegant.
So, um we just package everything from one React Native repo that you don't even have to like look at it.
You don't even have to know that it exists.
It just exists and sends packages to you and you as a native dev can just consume it and use it.
You're listening to React Universe on Air, your go-to podcast for all things crossplatform with React and React Native.
from talking with Mike Hujak, I don't know, it was like three years ago or something on that episode 13.
Um, he stressed that it's really important for brownfield project that want to integrate React Native in let's say big enterprises or something is that we like you said we don't disrupt the flow of existing developers.
If we have an app that has like I don't know hundreds of native screens already and we want to enable React Native for people that want to use it but then we don't want to interrupt everyone's workflow.
We don't want them to build React Native or Start Metro or anything like crazy like that.
They should be able to work with their app as they are used to.
And we are just adding on top of that another library, another utility that just allows you to do React Native.
So I guess like one way that I like to think about those React
And the reason is you normally have web views, they use they might use reactive and you have a special communication pattern with web views.
You have to like use some window.
event listeners to just like communicate with them.
And you kind of have the same approach with all the React Natives do except React Native can also have its own native stack and it's fully native.
So you can also use native APIs.
You don't have to write custom code just to delegate all those native calls.
Talking about native and React Native and that like integration layer between uh communication layer.
Uh let's go back to that um boundary that we discussed and let's let's maybe talk about what can we share, what should we share, what can't we share between the two words.
So that's a great question and my answer is as always it depends.
It depends on your use cases.
So it's always costy to send data between two systems because you have your native swift types, you have your native cotlin types, objective C types, and you want to convert them to JavaScript types somehow.
There are a couple of ways to do that.
You can use JSON, you can use JSI for direct access.
I'm not going to go into detail, but this always comes with a cost.
So it's not free.
So it's always a pros and cons of sending data between platforms.
I would say if you want the absolute best performance, it's always better to send as little as data as possible.
Let's say I have a like I have an app, I have my up state, my global app state.
I have like different screens written in different technologies, but I still want them to share the same data, to have the same user logged in, to have like the same products in the in the shop cart or or something like that.
So like what's
I guess now we are on a different realm because previously we were talking about sending data from native to JavaScript layer but now we have JavaScript to JavaScript communication and good news is that JavaScript share the same context and I guess like Oscar can explain it much better than me because he's been working with all those internals bridge.
I wanted to add to the uh before like passing data because uh you can always pass initial props from native to react native and this is probably the easiest way that you can pass data.
So it kind of works like I don't know server components kind of like you pass some initial data and you receive it in props.
So yeah, I wanted to add to this to the previous uh thing we were talking about that this is probably the simplest and the fastest way you can pass something down.
uh Burak uh please explain what we can do about like sharing the state across because this is a tricky tricky topic and I think like maybe like my question my question comes from my like general understanding of the apps like probably like the biggest thing that you want to share between those two realms is like your app state right?
Yeah, definitely.
So like um I would say at least you have to share some user token or something like that to show that you you have logged in.
Um I don't know if you are doing whole navigation stacks, you might also want to like pass some props but I think the best are and when I say best is arguably the best but I think it's always better to have less side effects in your code.
So one way that I like to think about those react native brownfield modules is if you can keep those uh side effects as minimal as possible and when I say side effects it's something like oh I have a native app call that changes everything
So the answer is yes.
And the reason why the answer is yes is because when you initialize a bridge instance it this was the old architecture and I think we have some similar API on new architecture as well.
It generates a single JavaScript context for you.
So if you have a couple of React Native screens that you use in your native applications.
I don't know maybe like you have a native screen that consumes two screens that are half sized each.
So they can communicate between each other using some sort of client state management library such as BDAX thanks to them being hosted in a single JavaScript memory.
So they will know
So say we go back to the example from Oscar that our settings screen is in react native and then I have completely different screen like in completely different part of the app.
Those two screens by default share the same JavaScript context.
They can talk with each other.
How about and this this will be another digression.
I'm sorry.
How about if I want to use like different React Native versions for those different screens?
Can I create two different contexts?
Now you have some technical depth because probably not.
The native code is the same but you can have v like react native factory.
It is a factory to create react native new instances.
So you can technically have two react native instances and two separate um hermes instances for you to have two JavaScript contexts.
And we actually uh used it on client project once uh for a PC so that you could have like a safe uh environment to execute JavaScript.
So you have one instance for React Native and we create a new instance which is totally separate JavaScript instance totally separate Hermes and like React Native to have a safe environment to execute uh JavaScript separately from your main app.
So the use case is to force those two separate contexts so that they don't share uh anything between them.
The main goal was for AI to have a safe context to execute something uh so that it doesn't like you know create some side effects.
Yeah.
So it doesn't like inject something into global that can affect your main app.
It has a separate global.
So uh that was the main main goal to have a safe environment for AI to generate code.
That was our main uh idea.
But you can also use this for example for um mini apps where you have
But that also comes with its own overhead, right?
It's not like Yeah, it's not free.
Yeah, it's it's definitely you have to create a separate React Native instance which is a cost in itself.
Yeah, go by memory.
You've been talking about like cost in terms of like memory management, processing power management or something like that.
I also think about the cost of complexity and cost of like dealing with this kind of repository.
Then we already have a brownfield integration.
Now we have to think about all of those other layers of complexity.
probably like the best practice approach would be to keep the complexity as minimal as possible because we already are adding a lot of complexity like it's always a trade-off between like developer productivity debugging time and complexity.
So I guess like if you can keep the dependencies as minimal as possible it's the best as it can get.
That's why like I was talking about having code that is side effect free so that doesn't have a lot of dependencies between realms.
Okay, looking at my notes, I think we went over a bunch of things from like React Native brownfield.
Is there any anything that we missed that you want people to know about like using this this technology?
So I guess like one thing that I would like to add is this yeah like today's it's this might still require some some sort of expertise in at least some native code in React Native.
So it might be a um like huge stopper for some teams to adopt this technology but it's getting easier and easier and we are working on this area to improve it.
So uh maybe like today you're not able to find a lot of resources but I would say
It's it's it has huge potential because rewriting sucks.
So we we want you to keep as much as code as possible operational so that you can move even faster.
I'm thinking what what Oscar said about like adding all of those generalizations to React Native.
I'm thinking React Native has matured so much in this like green field approach that the like the obvious way for us to grow for our technology to grow is to incorporate the brown field and to embrace the brown field because this will open up for us new possibilities and I think the market of crossplatform is going that direction as well.
So uh linksjs this new framework from bite dance I think it's brownfield first and it allows not only react but it allows a bunch of different like framework technologies.
I think brownfield is the next front frontier for us.
uh new platforms are also like uh a way for us to grow and it's exciting to see so much so much movement in in our crossplatform space not only in react native but like I like I mentioned linksjs we can borrow and like learn from each other a lot I think in that regard what do you guys think yeah definitely I think like this is a great point to um compete with react native for links because if you have a technology that's called links and you want people to use it, you cannot just be like, oh, like now you just have this and create a new app.
No, that create a new app is what I think what's what's stopping people from trying these new technologies.
I think it's the best that we let them use it as they want so that they don't have to create a new app.
They can just use their own code.
I agree 100%.
And have nothing to add.
Yeah, maybe guys you can tell us the last thing is to where can people find you?
Where is this React Native brownfield library docs, podcasts, etc.
?
Yeah, so it's on our GitHub uh on the call stack, github.
com/call stack.
Uh you can find the react native battlefield.
I think if you type into Google React Native profit, this is the first thing that pops up.
So um check it out.
Uh you can find me on Twitter and GitHub.
I'm there uh under the handle o kashnvki.
I just searched Oscar Kashnvki in Google and your website is the first result for me.
So you're easily googleable.
You're not going to be able to find me.
No, my name is so generic.
Okay.
And you can find me at ax_atlj.
Okay.
We will link all of your profiles and all of the links in the show notes.
And if you want to follow Colag, we are easily findable on the web.
Just follow us on everything.
We started releasing those episode on Twitter on X as well.
So you can watch us there.
Uh let us know how you like this episode.
We are waiting for your comments.
And thank you guys so much for joining me.
I had a blast this morning with my coffee and my Red Bull.
And see you somewhere in the near future.
See you.
See you.
Thank you.
See you.
Heat.
Heat.
[Music]
Is rewriting your app from scratch the only path forward? Not quite.
In this episode of Coffee Talk, we dive into a smarter alternative: React Native Brownfield integration. It’s a practical way to bring cross-platform power into existing native apps—without blowing up your architecture or CI pipeline.
Join Łukasz Chludziński and his guests, Oskar Kwaśniewski and Burak Güner—core contributors to React Native and the minds behind brownfield tooling—as they unpack how modern integrations are evolving.
With firsthand experience building at the edge of React Native Core, they walk through the patterns, tools, and decisions that make large-scale brownfield integrations viable today.
Reinventing React Native Brownfield
Brownfield used to be brittle: manual bridging, chaotic initialization, version mismatches. But that’s no longer the story. Thanks to recent updates in React Native Core—including factory APIs like RootViewFactory
and ReactNativeFactory
—brownfield setups are cleaner and easier to scale.
Even better, with the release of React Native Brownfield 1.0.0, Callstack’s library now supports:
- A simplified, more predictable API
- Packaging as a native framework
- Compatibility with SwiftUI and Jetpack Compose
These updates make it easier to reason about hybrid apps, reduce integration debt, and align React Native with modern native paradigms.
What you’ll learn about brownfield app development
- What really separates greenfield from brownfield—beyond the buzzwords
- How new factory APIs eliminate boilerplate and make setup consistent
- Tips to avoid side effects and keep your codebase clean
- Why native framework packaging makes modular adoption easier
- How this approach works for both legacy apps and emerging platforms like visionOS
- Where the performance trade-offs live—and how to manage them
Resources for exploring brownfield React Native further
- Łukasz Chludziński on X, Bluesky, and GitHub
- Oskar Kwaśniewski on X and GitHub
- Burak Güner on X and GitHub
- React Native Brownfield on GitHub
- Burak’s article Powering Native Apps with React Native Brownfield
- React Universe On Air #6: Brownfield Development With React Native
- React Universe On Air #13: Migration to React Native
We help teams introduce React Native into brownfield projects effectively.
Learn more about
Brownfield
Here's everything we published recently on this topic.
We can help you move
it forward!
At Callstack, we work with companies big and small, pushing React Native everyday.
Code Sharing
Implement effective code-sharing strategies across all platforms to accelerate shipping and reduce code duplication.
Migration to React Native
Plan and execute a migration from native or hybrid stacks to React Native with minimal disruption and clear technical direction.
React Native Brownfield
Integrate React Native into existing native application and start sharing code across platforms immediately.
React Native Trainings
Equip your team with React Native skills through tailored training sessions.
