Could you introduce your app in a few sentences?

Go Sitebuilder is an app which allows people to make and manage a website from their phone or tablet, including blogs and ecommerce sites. It's available on Android and iOS, and is aimed at people or businesses who want to create an online presence. It's made by BaseKit, where we have about fifty people in total, of which around six worked on the app. We've been working on it for around a year and soft-launched it a couple of months ago on both platforms.

What made you decide to use/switch to React Native?

Our main product - BaseKit - is a web app, and was already using React in some places, so it made sense to create the app using the skills we already had in the company rather than hiring specialist Android or iOS developers. This was also the first time the business had offered an app as well as our web version, so being able to have one set of code work across platforms meant (in theory) it would be quicker to get iOS and Android apps up and running so we could get feedback from them.

How did you transition to React Native?

The Go app was a completely new project for us, so we created the React Native codebase from scratch. The core of the app is essentially a wrapper around a web view, which accesses our existing web app. The rest of the app handles things like user registration and logging in, payment gateways and in-app payments, SDK integrations with Facebook and so on.

Generally, getting the app working initially was straightforward - we were already familiar with Webpack and NPM from our frontend code in our existing app, and there was plenty of documentation on getting started with React Native. There were a few cases where things didn't work as expected - for instance, file uploads don't work in Android web views, so we had to find a third-party library to work around this. Another area where we had problems was with passing messages between native code and webviews, and again we had to find a third-party library to fix the problem, but generally getting a basic version working wasn't too problematic.

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

I've used Cordova before and quite like it. Compared with React Native, it feels more like the focus is on wrapping a web app and allowing access to native features, while React Native is aimed at creating a native app, which also happens to allow wrapping a web app in a view.

Cordova feels a lot more mature than React Native, both in terms of the tools themselves and the ecosystem surrounding them. React Native has (or can have) breaking changes with every point release, so every update comes with a large amount of tension, since you don't immediately know whether your app will still work or whether all your dependencies support the new version. We found that with React Native you need to always check every latest release and try to update your code as soon as possible, otherwise you'll get stuck multiple versions behind which turns upgrading into a mammoth task, and you'd want to upgrade to get better performance or to reduce dependencies on third-party libraries.

Having to rely on a lot of third-party libraries with React Native meant that we often got stuck on a version since a key dependency hadn't updated, for instance the file upload library mentioned earlier. This meant we either had to spend time fixing the library and sending a pull request, or finding a fork or replacement which worked with the current React Native version. We chose to use React Native in part so we could get a minimum viable product running quickly, but having to maintain external dependencies slowed us down a lot.

React Native's build process feels a lot more rickety than Cordova's; there were times we would get different results running the same command. We would often get obscure error messages which were difficult to find answers for, either because fewer people had these issues than with Cordova or because they were generic errors from iOS or Android build tools, so weren't specific to React Native. Cordova tended to have more comprehensive information, even if that was from Stack Overflow, mainly due to it being around longer and having stable versions.

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

Go Sitebuilder was written from scratch, so we don't have anything to directly compare it with; however, performance seems fine and we don't have any issues with the speed of the app.

How has adopting React Native affected developer productivity?

Generally productivity was pretty good to start with, but definitely went down as time went on. When things work it's great, but when they don't it's pretty horrible.

Debugging in the browser is really handy, especially as it uses browser devtools we're already familiar with. Hot reloading is also great - no long compile times to check changes, and having a key to instantly reload the app is also really useful. Being able to target Android and iOS with broadly the same code has been a huge benefit to productivity, and React itself seems pretty popular in the team.

When things go wrong, however, it tends to take up a lot of time to fix. We had occasions where building worked on some machines but not others, and error messages were generic platform ones so were tricky to find answers specific to React Native. The build process often felt a bit rickety and seemed to rely on global libraries installed on your machine - after checking a new version of React Native, rolling back to an older version broke my build even after reinstalling all my node modules and the global React Native CLI. The only fix was to open the project in XCode, remove all pod libraries then re-add them - I still have no idea why that happened, and there's next to nothing on Stack Overflow or Github to help explain what was going wrong.

Having third-party dependencies also took up time with finding compatible versions and making sure that they would work with newer versions of React Native before we upgraded everything; running into edge cases (like the Android file upload issue) also meant that we had to spend time finding a solution to things we expected would work. Upgrading the React Native version was the biggest problem we had that cost a lot of developer time: React Native doesn't use semantic versioning so every release can, and often does, have a breaking change, which meant we needed to check every single dependency we had with every new release. Since these libraries were also updating with the new releases, there were often delays in supporting new versions, and sometimes libraries ended up completely abandoned when the maintainers no longer had time to update them.

Overall React Native has been good for us to get up and running, since it allowed us to create apps on different platforms without having to retrain - vital for moving into an area we hadn't focussed on before. However, the problems we encountered have stacked up to the point where we're seriously considering moving to native versions so we can be confident that updating the apps won't mean lost days of developer time with broken dependencies.

We're still using React Native, we're just on an older version while we get dependencies sorted out and debate whether to rewrite the app.

Build tool: Make (handy for wiping intermediate builds or installing pods/dependencies)

State: Redux

Webview-app Communication: react-native-webview-bridge

Polyfill: react-native-webview-file-upload-android

Testing: Jasmine, Enzyme

Linting: ESLint

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

I used the examples and tutorial on the React JS site when learning React, and the same with Redux. Since I already had a background with React, the overview on the React Native site was about all I used to get started with apps, other than answers on Stack Overflow.

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

As mentioned earlier, the key area for improvement in React Native is the API stability - it really needs a stable release so libraries can catch up and pin to a specific version, and would mean that there aren't constant breaking changes in the core library. Just having a stable version to use would solve almost all of the development problems we had in building the Go app, and would also mean adding or updating third-party dependencies would be far less painful.

It would also be nice to have better error messages, or more comprehensive documentation around what the errors mean in the React Native context, since they are often generic platform messages which can be tricky to find a React Native-specific answer for.

Anything else you would like to mention?

React Native is pretty good when it works - being able to debug in the browser is great, and targeting multiple platforms is really nice - but it feels like it needs more work before I would consider using it in another project.