Which problem are we solving?

React (the DOM variant, the one for the browser) and React Native look similar, but solve different problems. Let’s look at React first.

Modern browsers are powerful, but they don’t really help you ‒ the developer ‒ as you create your UIs. The browser will gratefully run your JavaScript and render your HTML and CSS, but without help building seemingly simple UIs means writing a lot of code and markup.

This is where React comes in: it empowers you by allowing you to create UIs with less code. React even persuades you to make the code that you do write easy to read and understand. At what cost? Well… sure… with React there is a “performance ceiling” in rendering which you can only break through by taking out the middleman. React also makes your JavaScript bundle a lot larger. But for many projects, this cost is not relevant. For many projects, using React is almost free.

React has such low cost because it focuses on UI and does not affect any other aspect of your app. This is its beauty.

Android and iOS, contrary to the browser, have always been helpful to developers creating their UIs. Building a UI directly onto Android or iOS might not be as smooth as building it onto the browser + React, but there is definitely not as much need for a React here as there is a need for React for the browser. There is not as much need for a “React Native”. At least not for this reason.

Instead, React Native does something completely different: it allows you to build UIs which you can deploy on both Android and iOS. Without porting. This is a thing many different camps have put quite some effort into over the years. I honestly feel RN is the first to do it in a way that is viable for an average project.

But at what cost?

By design, React Native-powered UIs live inside a gated environment. As a result, the non-UI code is split across the gated environment (and written in JavaScript), and the “native” part of the app (and written in Kotlin, Java, and/or Swift).

And there is a catch to both sides. Code that goes into the native part can’t easily communicate with the UI. Code that goes into the gated environment, however, can’t easily access the APIs Android and iOS offer.

The RN community will be quick to tell you all code ‒ UI and non-UI ‒ should go into the gated environment, and be written in JavaScript. This means you will have to build a bridge for every Android or iOS feature for which RN doesn’t provide a bridge out-of-the-box, or rely on third party libraries. This also means the architecture of your app will have to be moulded around bridged communication. It is a realistic option, but you could end up with hard-to-read code. You might even find yourself leaving out subfeatures because they “take too much effort to implement” now that you are using RN.

An exercise for the reader: build an RN app which opens up a camera app on the device and uses the photo that was taken, or finds the music on the device and plays a song. (Extra points if you do the same in Android.)

The beauty of React did not carry over to React Native: React Native changes every aspect of app development, not necessarily for the better. The RN community will try to fool you by commenting that this is “just something you have to deal with”. But it’s not: it’s something you have to deal with if you use RN.