/ Programming

My Thoughts on React Native

Latest update: Feb 17th, 2018. This article is still in progress. You can help me finish it, by giving me some feedback in the comments down below or on my blog's subreddit.

UPDATE Feb 17th, 2018: Though not a part of this article, it is worth noting that Facebook changed the licensing of React Native to MIT yesterday. This should come as a relief to many and would certainly increase the library's commercial adoption even further:

When I was younger (and way out of money), I dreamed of having a slick, brand new electric guitar. Every day, I was checking it out, hoping for the moment, when I would finally be able to afford it and tour the world, like most of my teenage idols. Eventually, the day came, and exalted, I headed home, imagining the endless solos I would finally be able to play on it. Much to my surprise at the time, the guitar sounded incredibly crappy. Moreover, the more I forced myself to play it, the crappier it sounded. Frustrated, I tucked it in a dark corner of my room, where it stood for more than a year. Eventually, I picked it up and we have been best buddies ever since, but by this time, I had realized that the guitar was just a tool. Even the best tool in the world can't help you if you are using it for the wrong job.

Much like my electric guitar, React Native is a well-designed tool. It can serve you well and be your best friend if you use it appropriately. On the other hand, false expectations might lead you to frustration and headaches. I decided to share what I've learned from my brief experience with React Native, and give you my (slightly opinionated) view of how to you use it to your advantage. Perhaps, I would rather start with what it isn't.

React Native is not a Web technology...

...as much as you want to believe it is. Indeed, React Native uses a JavaScript runtime and follows the conventions laid out by React and the JS programming community. You can integrate most of the available JavaScript libraries as part of your apps, and use the same tools for dependency management, testing, and building, which a Web developer might be familiar with. However, this is pretty much the point where the Web-like part finishes.

It is important to note that React Native is not a full-fledged framework, but a library used by, and wrapped inside a native mobile application. There's this notion around RN, perhaps driven by the ease of use of its CLI toolkit, that it can be used for generating cross-platform apps per button click. This is misleading. At the end of the day, React Native is a library which can be integrated into every existing iOS or Android project, and used just like any other library the project depends on. Correct me if I am wrong, but the whole idea about the creation of the library, was to share the massive boilerplate code between the Android and iOS versions of Instagram, wasn't it. The fact that one could create entire apps where React Native is sort of the main actor, was more of an afterthought at the time.

This should come to confirm the point that using React Native does not mean you can escape native app development completely. React Native has been created to augment the current state of app development and reduce boilerplate, but it was never meant to replace it. You have to have to have an understanding of the underlying intricacies of the mobile platform you are building for. Move two steps away from a basic ToDo app, and you end up reading about linking C libraries and fixing Gradle bugs. And this is all perfectly fine. Because, this is what a mobile developer does for a living. Did you expect something else? I am sorry to have disappointed you, but that's not what RN will solve for you. At least, it did not for me.

That leads to my second point, which is that the build-it-once-use-it-everywhere approach won't work. You can absolutely share 100% of your React Native codebase between iOS and Android. You should however also keep in mind the fact that your app might end up looking like a poor compromise on any of them, unless you work on the native-level polish. What developers coming from the Web fail to understand, is that every mobile platform has its intricacies and what works on one may not work on the other and vice versa. While perfectly OK for prototyping an idea and quickly bringing an MVP to the users, when an app project grows, the different platform versions of it will eventually diverge, and that's actually a good thing.

Where React Native Shines

Having emphasized enough on the fact that React Native is not a sort of magic box that makes an app ready out of nothing, but rather, a helper library, let's see what we can use it for. IMHO, the two biggest selling points about integrating React Native into your project, are:

  • Cross-platform rapid prototyping of a new app idea (with all the caveats that this brings, of course)
  • sharing a balanced subset of your code base between different mobile platforms (let's stick to iOS and Android for now).
  • updating your apps more frequently, by downloading the shared JavaScript part directly from a server.

Point one is where most people get excited when they hear about React Native for the first time. Indeed, in spite of everything I have written so far, if this is what you want, yes, RN can help you achieve it. That is, assuming that you are OK with using common UI components present across all platforms, and not care much about performance and native touch and feel. To be honest, for testing out quick and dirty prototypes, why should you? Grab a copy of the RN starter kit and sketch out your idea! I am not going to go into further details on this point, because there are thousands of resources on the Web, illustrating how to make a cross-platform app in less than an hour. This is generally not the point of this article.

For anything other than a prototype, one should assume that active native development is needed, and React Native is primarily used to help reduce the boilerplate between the different platforms. There are two ways to approach integrating React Native into a native app shell. The one is the top-down, where one would design the rough skeleton and workflow of the entire app using RN, but bridge to components developed natively for each platform. This includes bridging both UI (native views, assets, etc) and non-UI components (state managers, network handlers, event bus, concurrency management, persistence, etc). For a large chunk of those, the library already provides reasonable default bridges, for the rest, creating custom bridges between the Js runtime and the native platform is doable, though at the cost of some additional work. The benefit of using React Native as a top-down solution is a shared copy of the entire business logic and app workflow, without compromising on the native look and feel.

The opposite of the top-down approach, would be a bottom-up one. This one would be more appropriate for apps that have been in development for quite a while and already have established native codebases. Imagine a company, willing to introduce customisable widgets inside of its Android and iOS apps. A good example are CTA-s (call-to-actions) and other marketing gimmicks that often need easy customisation, in order to match to the individual user. The cost of developing and maintaining such components natively would increase with time, so sharing their codebase using React Native an embedding inside of native apps may prove to be quite cost-effective, without compromising on the native look and performance. This is for example, how Instagram has been using React Native.

Stay tuned for the final part of this post...