Could you introduce your app in a few sentences?

Pinterest is an app on iOS, Android and Web to help you discover and do what you love. We use Pinterest to get inspiration for design, find new recipes to make, and keep track of books to read. Recent Pinners in those areas that we have followed include Salih, Molly Yeh, and James Patterson.

What made you decide to integrate React Native?

We chose to evaluate React Native because of the potential improvements in developer productivity. Shared code between mobile platforms would save developer time, both in terms of reducing the number of dedicated mobile engineers needed for each new feature as well as the ongoing cost of maintaining already shipped features. It was also exciting that we would get these developer gains without any sacrifices to the user experience since we could still get the native look-and-feel.

React Native was immediately a compelling technology because we already were using React for web and mobile webapps. The company had already invested a lot in integrating tooling and testing frameworks. Therefore, adopting React Native would allow us to leverage the existing expertise in the company.

We also wanted to bring the mobile and web development ecosystems closer together by building React Native components from the get-go that conform to Gestalt, the open-sourced set of components used by the Pinterest web app. This way, we make it easier for web engineers to onboard onto mobile feature development by implementing the same shared React paradigm and the same component library APIs they were used to using for web.

How did you integrate React Native?

We built an internal prototype and recorded the feature development speedup from using React Native. Once we had a working prototype, we conducted an internal technical evaluation to evaluate performance and make sure the UI was at visual parity. Then once we found out as much information as we could internally, we launched an A/B experiment with the React Native features to assess real user metrics. You can read more about the process in detail here.

The three of us had some familiarity with Javascript and had been following the React Native community with interest. Although it did require some time to learn React Native, the ramp up time was definitely faster than learning an entirely different native mobile platform.

Have your tried other cross platform technologies before using React Native?

We have tested webviews within our native apps but generally found that the user experience was sub-par. Otherwise, any benefits of cross-platform technology outside of React Native would be overshadowed by the enormous organizational cost to get our mobile teams with dozens of native developers to transition to a new technology.

Other than mobile rendering technologies, Pinterest has many cross-platform internal services that power important parts of our mobile apps. One great example is the Experience Framework, a system built to manage product experience configurations. This was explicitly built to handle behavior and scheduling across all the platforms.

What has your experience been working with React Native in terms of app performance, have you noticed any impacts?

We decided from the beginning that the Pinterest app was not going to be rewritten in React Native. We considered the technology another useful tool in our toolbox, along with all of the fantastic capabilities of native mobile technologies. Therefore we didn’t run into cases where we needed to create explicit workarounds because of performance. We currently constrain our usage of React Native to full-screen flows that don’t need highly optimized performance, like infinitely scrolling image grids.

And since the app existed before we integrated React Native, we could wrap our existing optimized frameworks to be used on the JS side. For instance, we rely on our open-source PINRemoteImage framework on iOS for fast image downloading and caching. On Android, we use Picasso for image downloading. Any image rendered with React Native will still use the underlying image framework for the specific mobile platform.

How has adopting React Native affected developer productivity?

We were able to implement our initial prototype screen on iOS within 2 weeks and brought it over to Android within 2 days. This also included the initial integration steps to get React Native running in our app. The fact that we were able to implement this screen in such a short time frame convinced us to adopt React Native on further screens and open it up for other engineers within the company.

Another great example of the velocity improvements is our business signup flow. An engineer with only React experience built our business signup flow on both mobile platforms in 1 week. We were able to test on both platforms at the same time and it was shipped on both platforms. If we would not have React Native available we would have to allocate at least one iOS and Android engineer for the project to build the business signup flow. Oftentimes features built natively are tested and shipped on one platform before the other.

Native engineers without any React experience in the past definitely have more problems with getting started and ramping up within the React Native world. However after the initial ramp up, there is positive feedback about development using React Native. Features that native engineers like especially are hot reloading and code sharing across platforms. For example, currently an Android engineer is implementing a flow that is planned to ship on both Android and iOS. This is possible using React Native even though she has never done iOS development before.

In terms of tooling we tried to have it straight forward and tried to use the same tooling that were successfully used within our web codebase. The tools we use are:

Flow for type checking

Prettier for code formatting

ESLint for linting

Jest for testing

For our web app, we use our own open-sourced React UI component library called Gestalt. We are adding React Native support for Gestalt, although the React Native implementation has not been open-sourced yet.

There is not much available infrastructure for integrating React Native into brown field apps, so we created some small internal libraries that help us to bridge the native and React Native layer as well as bridge infrastructure like crash reporter or experimentation framework to our React Native layer.

What resources have you used to learn React Native? Books, tutorials, courses etc. Anything you can recommend?

All of us working on the initial integration have native mobile development backgrounds and have worked on iOS or Android for quite a couple of years now. We also already had a bit of experience working with React in the past. Therefore we mostly used the official documentation or the source code directly to fix problems or address missing pieces of knowledge. This was especially important as there is not much knowledge available yet on how to connect the native and React Native world when integrating into existing apps.

That said I would say, and that is not only relating to React Native, but one of the most effective ways for me to learn new things is to code and work in that domain as much as possible. There is no better way to get knowledge as doing hands-on work and running into all kinds of issues and problems, trying to solve it by yourself, and collecting your missing knowledge from all kinds of different resources.

What are some things that you don’t like about React Native or that need to be improved?

Integrating React Native into existing applications with other build systems such as CocoaPods on iOS or Gradle on Android is not really straight forward. We are using Bazel to build our iOS application, and pulling in all third party dependencies like Yoga, Folly, Boost for React Native etc. Making React Native play nicely with Gradle was non-trivial. But on a positive note, due to the complexity, we were able to vastly improve our tooling to generate Bazel BUILD specificiations out of CocoaPods specs via PodToBUILD, an open source tool we use to integrate 3rd party dependencies into Bazel.

As we started to look into integrating React Native into our existing native infrastructure, there was not really much information or existing libraries available. Most of the pieces we that we have in place were discovered through reading the source code to see what was possible. We may plan to open source a couple of these components and libraries in the future. We are also considering publishing articles to share knowledge and make it easier for further companies to integrate React Native in their brownfield apps.

It was exciting to hear plans from the React Native Core team about making improvements in the framework layer (e.g. providing synchronous calls into React Native) in their recent blog post, State of React Native.

Anything else you would like to mention?