Bringing the New React Native Architecture to the OSS community

Bookmark

At the end of 2021, we successfully rolled out the New React Native Architecture in the Facebook app.

Now, it’s time to empower every React Native developer on the globe to use the New React Native Architecture, both the new Fabric renderer and the new TurboModule system.

But migrating an entire ecosystem to a New Architecture is no easy task.

To support the whole community in this endeavor, we lined up a set of tools and materials that will help both app and library developers to join us in this journey.

In the talk, we will present how the New React Native Architecture looks in the OSS space. We will discuss the impact this will have on developing React Native projects. Lastly, we will cover what we learned from the React Native New Architecture migration at Meta, and how you can tackle your migration in your organization.

by



Transcription


Hi everyone, and thank you very much for joining me in this session. Today we're going to talk about bringing the new React Native architecture to the open source community. Mandatory slide about myself, my name is Nicola Corti and I work as an Android engineer in the React Native team at Meta. You can find me online as Cortinico either on Twitter or on GitHub. As we have so much to cover, let's jump straight into the content. So if you were to search today React Native new architecture on Google or on YouTube, you will find actually quite a lot of content. I want to focus a little bit on YouTube because there are several videos that are actually really valuable. And as you can see from the dates, we actually started talking about React Native new architecture in 2018 at ReactConf. So much time has passed. The last talk is from 2021 React Native EU from my colleague Joshua Gross. I actually want to invite you to watch the talk if you haven't yet. Joshua in his talk was talking about the timeline of the new architecture and how long it took us to do the rollout of this technology, which essentially is a major rewrite of the React Native internals within the Facebook app. It took us essentially three years. And so I want to start from this timeline, from what Joshua said in that talk. And where do we go from there? So he mentioned that, again, we started in 2018 in Q2. And initially this project was supposed to last roughly six months. But the reality is that React Native is used so extensively inside a Facebook app and a lot of teams try to squeeze as many milliseconds of performance from every screen that rolling out such a big change was quite a challenge. That's why it took us so long and in 2021 we finished to fully roll out the new architecture, specifically the new render fabric on all the surfaces of the Facebook app. And then, well, what's next? What's next is that we looked at the open source community and we actually wanted to allow everyone out there to benefit from this new major rewrite of the internals of React Native. So what comes next is actually rolling out the new architecture outside of meta and empower everyone to use what we developed so far. And that's where we are now. So end of 2021 and beginning of 2022, we started creating content and material to empower people outside of meta to use the new architecture. So today I'm going to present a lot of material and content that we developed so far and that will help you embrace the new architecture of React Native. But first, I want to reiterate a little bit on the why, because I get asked over and over why should I migrate to the new architecture? And if you still haven't got it, the why is all about the bridge. The new architecture is essentially a substantial rewrite on a lot of components of the internals of React Native that allows us first to get rid of the bridge. The bridge was a component that was making possible the communication between the JavaScript layer and the underlying native layers. With the new architecture, this component is essentially gone. And with that comes a lot of improvements in terms of performance and generally like is a restructure of the internals of the framework. As we wrote a lot of the internals, we actually took a stance to reimplement a lot of the rendering pipelines and the internal components of React Native using a shared language. So we decided to use C++ to, again, have a single implementation of the renderer that allows us essentially to reduce a lot of discrepancies between different platforms. Historically, there used to be different renders for Android and for iOS. So things will behave a little bit different on the two platforms. Thanks to the new architecture, we are essentially having a single implementation of our internals and we can ensure that whatever we develop is consistent within the two platforms. Similarly, we can also reshare a lot of the optimizations we developed for one single platform across all of them. And this is possible thanks to having a single implementation of the renderer and internals. We also took a stance of the developer experience and we tried to implement a lot of best practices and blend them inside the core component of the React Native new architecture. Specifically, we developed one component called the Cogent that allows us to bring type safety inside our code base. And finally, the new architecture is, as I said, about performance, but also about a lot of new capabilities that we are building on top of those new foundations. So it's sort of like we took a stance, we wrote a lot of internals, thinking about what new capabilities this allows us to develop in the coming years. So whenever we refer to the new architecture, we refer to a lot of components that we often call pillars. So the new architecture of React Native is actually composed by several pillars. We have Fabric, the new renderer. We have a new native module system, which we call the Turbo Module. We have a component which allows us to generate code, which is the Cogent. And we also have the Bridgeless mode. So once all the pieces are together, we have the capability to essentially remove the bridge component, as I said before. This is called Bridgeless mode. I want to zoom in a bit on the Cogent and give you a glimpse of what we envision is the developer experience on the new architecture. So as I mentioned before, type safety. And the whole idea behind the Cogent is, let's say the developer is writing a TypeScript file which defines the API of a native module. In this case, they will define a spec, like an interface with a declaration of all the capabilities of this module. For example, this module is able to answer the ultimate question and takes in input a string and returns a number. And the user will then just register this Turbo Module. The Cogent works at this level. It focuses on this function and the input type and the return type. And from that, it generates code, a lot of boilerplate code that in the past developers will have to write manually for both Android and iOS. So let's take a look at that. On Android, we're going to generate an abstract class with constructor and a specific abstract method that adheres to the signature of the spec that we saw before. So we are going to have a function that takes in input a string and returns a double. It's an abstract function, so it's up to you to implement it and provide the correct business logic. Similarly, on iOS, we are going to have an Objective-C protocol that takes in input an NSString and returns an NSNumber. So we do all the heavy lifting of all the typing from JavaScript layer to the underlying layer and we generate code for you. So you just have to implement the business logic. I also want to talk a little bit about the build tools, because as we worked on the developer experience and we introduced the Cogent, we had to do a lot of changes on how things are built. Specifically, there is also a lot of C++ code that we need to build now, which previously we would have not need to. So there are some changes that you might see and I want to clarify a little bit of topics. As you probably know, the build world within Meta and outside is a bit different because internally we use Buck to build a lot of our code, while externally we can't expect users to install Buck and use it for building everything. So we need to adapt to the platform standards. Specifically on Android, we have Gradle. So what we did, we did a lot of work around the C++ code. Users will find references to CMake files or Android.mk files, which will allow them to build their native code. So we don't have just Java and Kotlin code anymore, but we also have some C++ code to build. For Java and Kotlin instead, we spent a lot of time building the React Native Gradle plugin. This is a set of build logic and tools that allows to build essentially React Native application. And this is going to replace in the long run, the good old React or Gradle file that we all included. On iOS, we follow the similar approach. So we have CocoaPods and we developed custom logic in Ruby that allows us to call the code gen and integrate within your build logic. I also want to spend a couple of seconds talking about Hermes, our in-house JavaScript engine. So if you read the documentation for the new architecture, you will find that Hermes is currently recommended. So you will have, we highly suggest you to use it because it's the way how we can support you better. We are moving towards having Hermes as the default engine for React Native. And starting from React Native 69, every version of React Native will come with a so-called bundled Hermes version. It means that for every version of React Native, we are creating a version of Hermes that we know is compatible with that specific version of React Native. This brings a lot of improvements in terms of stability for the engine and essentially gives you an engine that is ready for you to use bundled together with React Native. I also want to spend a couple of seconds on modern languages because we get a lot of questions on this side. On the TypeScript side of things, whenever we release, when we release the first iteration of the new architecture documentation, we add a lot of comments from users that were unhappy that the initial iteration of our tooling supported only flow. We obviously want to make sure that React Native is used and supported within the broad ecosystem of web and mobile developers. So we spent time adding support for TypeScript. So I'm happy to announce that the code gen for the new architecture now fully supports also TypeScript. So you can write your spec in either flow or TypeScript and the code gen will just generate code for Android and iOS starting from those. Moving on Android, we have Kotlin. So on the Kotlin side of things, well, Kotlin is luckily fully supported in React Native. You can write your module and components in Kotlin. We are also doing a lot of effort in updating our website to be bilingual. So if you open this issue, React Native website 3018, you will find what's the current status of the immigration of the website in being bilingual. So you will find docs for Java and Kotlin on several pages already. And you can expect the new app template to be updated to be fully Kotlin in the future. We just haven't done it yet because we want to focus on the new architecture for now. Or you can expect this change to come in the near future. On iOS instead, we have Swift. A lot of users asking us how they can do to write their component and modules with Swift. Well, that's a little bit more complicated. We're actually looking into it. But due to interoperability between Swift and C++, things are a bit complicated. So expect some news in the future. But sadly, I don't have anything to share at this point in time. So now I talked a lot about new architecture. I also want to clarify a little bit what's the timeline and what are the versions that we released to give you an idea of what we released so far and what's coming next. So React Native 68 is the first version that fully supports the new architecture. Theoretically, the new architecture was already released some versions ago. But we haven't provided an easy way to use it. So 68 is the first version that has a one-liner that you can enable to just try the new architecture and start writing Fabric Component and Turbo modules. React Native 69 is the first version that adds supports for React 18. If you follow the development on the React side of things, React 18 is a major release of React, contains a lot of new features. And I'm going to talk about the implications between React and React Native in the next slide. As I mentioned, 69 also contains bundled Hermes alongside a lot of improvements on the new architecture side of things. Then we have 70, which is the next versions that we're going to cut. It will contain several other features that will help users on the new architecture, specifically Android auto-linking support, which was auto-linking support for new architecture was already there for iOS, but was missing on Android. So we had to do some adaptation and this will land in 70. There will be also CMake support end-to-end, so users can write their C++ code with CMake. And there will be also support for unified code gen config. We received a lot of feedback that the way how the code gen was configured was different between Android and iOS. So we took a stance and fixed this. And well, 71, I like to say today, infinity and beyond. React Native is developed at Meta, but it's also a community, is a project where the community is placed first. So we really hear what's the feedback from our users and we try to integrate it as much as possible. Some of the features that will be going out in 70 are actually there because we received feedback from users, which they really needed those features. So if you feel that there is something that is not working for you, please let us know. Tell us what is not working. Tell us how we can improve the new architecture experience. We are so looking forward to that. As I said, I want to spend some seconds on the interactions between React Native and React 18. And here I have a table for you to explain. So if you are on React Native 67 or React Native 68, you're essentially on React 17. Even if you go in your package.json and you change your version of React, you are still consuming React 17. The reason is because the versioning of the two frameworks is tightly coupled. You can't just bump one or another. Things do not work correctly. React Native is having a bundled version of React, the React render inside, so we'll discard the version that you pass in the package.json. If you want to use React 18, you then need to upgrade to React Native 69. But here there is a catch. React 18 ships with a lot of concurrent features and new APIs, such as start transition. Those APIs rely on the React Native new architecture. So if you are on 69 and you enable the new architecture, you can use those APIs and benefit from those concurrent features. If you are on 69, but you're still on the old architecture, you're still using a legacy version of React. Even if it's React 18, you will not benefit from those APIs. So I hope you understand how critical it is for users also to update to the new architecture because you will not benefit from those new improvements and API that we worked on in the last years. Okay, so I spoke a lot about frameworks, updates, and so on. Now I also mentioned about the new architecture documentation and material, but I haven't presented that yet. So I want to spend those last minutes talking about which docs we have available for you. And I want to stress how docs are important because when I was listening to this episode of the React Native show, I remember they asked the audience, what are you so looking forward in 2022? And one of the comments was the new architecture. But well, a lot of other frameworks have been using some pieces of the new architecture, but what is missing is the docs. And that's actually true. The new architecture was there and it could have been used in some form since previous versions of React Native, but without proper docs, the community will never understand how to use it properly and it will be too hard for them to use. So let's look at what we have so far. First, we have the official docs. So inside the guides section of React Native, there is a new section called the new architecture that contains instructions on how to enable the new architecture from the perspective of a library author and from the perspective of an app author. We are going to expand this documentation in the coming weeks and months. So please stay tuned as we have more to share. I also want to mention that we have a new section on the website called architecture. This section contains a lot of deep dives and documentation about the internal software native. We have been asked for this kind of docs a lot in the past. And so we spend time polishing our documentation on the internals and sharing like diagrams and explaining how things works internally. Little disclaimer, this documentation, these deep dives are not for everyone. Like if you're using React Native for the first time, you probably don't want to know the internals of the frameworks. But if you want to contribute or if you want to develop a more advanced component, you might need those information. I hope you will find it useful. So now let's talk about the new app template. The new app template is what you see whenever you do React Native in it, my awesome app. And we wanted this to be the primary entry point to the new architecture. That's why we worked on this part so much. And so for iOS, we extended it at pod install time. So normally you would run pod install, but now you can run it with this environment variable NewArchEnabled set to one, and that will configure your project to actually use the new architecture. You can just run with run iOS and you will be effectively running an iOS app on the new architecture. For Android, similarly, we have a file called Gradle properties and a property there called NewArchEnabled. You can just change it from false to true, and that will enable the new architecture for you. Again, you can run it with run Android and you will be running an Android application on the new architecture. If you want to be 100% sure that you are on the new architecture, you can check on Metro that you are running an app with Fabric true and initial props, concurrent root set to true. That means that you are using Fabric, TurboModules, the new architecture, and React 18 with concurrent capabilities and everything you need. We also spent a lot of time interacting with the community and produced more content. I want to present a couple more. First, the new architecture working group. The working group is a repository that is a discussion only repo where we allow users to collaborate and discuss about the new architecture topics. There are several sections like announcement, libraries, and documentation, and so on. I invite you to take a look. You might think if you open the working group that it's closed so you can't participate, but actually there is a link in the readme. If you click there, you can join the working group. There is a little form to complete, and then you'll be added to the working group. Finally, we also worked on sample repos. There are two sample repository that I want to share with you. The first one is the app sample repo, it's called RnNewArchitectureApp. This contains several branches which explains how to migrate your app from the old architecture to the new one. Specifically, here it's critical to see that there are several commits, and each commit is documented with a proper commit message. You can follow step by step how we migrated a simple project from React Native 67 to React Native 68, and we turned on the new architecture there. Similarly, there is also a library sample repo called new architecture libraries, and this contains examples on how to create fabric component and turbo modules that work both for the old architecture and the new architecture. So if you're a library author, you might find this really helpful. I also want to spotlight some of the libraries that did the migration already or started working on it. We strongly believe that libraries are critical to the migration of the old ecosystem, so I want to give a shout out to those libraries. If you're a maintainer of a library or an author of a library and you haven't migrated yet, please consider doing that. Reach out to us if you're blocked in any sense, and we're still looking forward to help you and understand if you're blocked in any sense and try to unblock it. And finally, to wrap up, I really hope that in six months, one year from now, whenever I search React Native new architecture, I will go on a search engine and I will find results about how you migrated your apps to the new architecture and how this was successful for you. What have you learned so far or how this was unsuccessful? And yeah, what didn't work for you? What are the pain points and so on? We are here to hear your feedback and we really want to hear your migration story. So please tell us. We are more than happy to spotlight success stories, feedbacks that you have to share with us and with the rest of the community. And with this, I want to thank you very much for listening. I also want to stress that React Native, React, Hermes, Metro, and all the other projects of the React family are open source and they're more than welcome to receiving your contribution. So thank you very much for listening. And I'm looking forward to see your contributions to the React Native GitHub repo or to catch up with you on the GitHub issue tracker.
25 min
21 Jun, 2022

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Workshops on related topic