This is the first article in a series in which I will be writing about React Native, how we use it to create applications here at Blazing Edge , and what it can do for you.

React Native, when used correctly, can be a powerful tool to craft native mobile experiences. At Blazing Edge , we are a bunch of JavaScript nerds through and through, so of course we love React Native. In this first blog post of many, I’ll be focusing on preparing a good development environment and configuration for deployment to real devices.

Agenda for this article

Introduction

New to React Native

Project directory structure

Running application on real devices

Development tools

Handling different environments

Tips

Summary

Introduction

Listen, there are probably 1000’s of posts about why you should use React or React Native for your next application. This is not one of those posts. If you are reading this article, you are most likely already hooked on React Native, so there’s no need to persuade you, but just in case, here are main reasons why we use React Native.

React Native is open source and there is a massive community around it. This means there are a lot of contributions to it, lot of custom modules to enhance app functionalities and a lot of different channels you can use to get help (Facebook, Discord — check tips section for links). While there are many small contributors, React Native has garnered the attention of some major companies. Big household names like Facebook, Microsoft, Airbnb, Wix, Walmart, and Uber have been known to use and contribute to React Native. People tend to think about React Native as a hybrid technology, such as Cordova, PhoneGap or Ionic. It is not! React Native allows us to write Javascript code which executes native functions on mobile devices to perform actions and render components. This allows us to have fully native applications, as if they were written in Java or Objective-C. React Native applications run at 60 FPS. This is crucial for delivering good user experience which is really hard to achieve if you are using a hybrid technology which runs your app in a Web view. Best of all, you write your code once and it runs on both iOS and Android without the need to customize anything. People usually talk about 80⁄ 20 rule where 80% of your code is shared between platforms, and then 20% of your code is platform specific. On our last project we had less than 5% of the code specific to the platform.

New to React Native ?

This article will cover many aspects of React Native and the development process behind every app.

If you are just starting with React Native, I highly recommend you check Expo.io . Expo is a set of tools that allows anyone to build React Native apps without worrying about the tools, IDEs, packages, native modules, etc.

Recently, I participated in a Reddit thread where a user asked if he can use Windows machine to learn and make apps in React Native.

You can make Android apps using React Native, but you won’t be able to test your application on iOS devices, since in order to deploy an app to an iPhone you need to have a macOS machine with Xcode installed. More about this whole process in the iOS section of this article.

However, if you are on a Windows (or Linux) machine, there is a way to test your application on an iOS device, and that is by using Expo which I linked above, which takes care of the bundling process (doesn’t require any tools or IDEs installed locally, such as Android Studio, Xcode, Android SDK).

While Expo is great for beginners, it does have its own limitations, like a limited offer of packages that can be used within an Expo project (maintained by Expo). So if you need to write native code or use some package/functionality that is not within Expo SDK, you’ll have to eject Expo from your application or use some advanced methods.

Read more about the limitations here .

Project directory structure

Here is a basic directory structure that you’ll most likely find in any React Native project, and if you had experience with React for the web, you’ll find src/ directory very familiar.

index.js

Entry point for every Android and iOS application. If you were using React Native before version 0.49 you’ll find this new. Before there were two files, each for each platform. Since they were always the same, it was logical for React Native maintainers to use a single entry point for both platforms.

android/, ios/

platform related directories

Most of the time you won’t even need to touch files within these directories because react-native link command does everything for you when you install new packages.

src/index.js

The JS part of the app entry file usually glues together small pieces that require access to the root component of the app, such as redux integration, over the air updates (more about this in the next sections), navigation library, deep linking, handling push notifications, etc.

src/components/

A directory with all reusable components used in the application, same as components in React

src/screens/

We keep all screens within this directory since all screens have access to the Redux store, there was no need to have a containers/ directory.

In this directory, we keep all screens which are registered by Navigation library on the application start so they can be accessed within the application.

.env, .env.example

More about these files in the Environment section of the post.

.vscode/

This is an editor specific directory used by Visual Studio Code to store all configuration for the project and editor plugins.

Running application on real devices

Android

Running the application on Android devices is easy to do, all you need is a keystore file and that’s it. Just be sure to always have this file backed up and passwords stored safely. Once you upload your signed app to the Google Store, you won’t be able to submit new versions of the app if you decide to swap an existing keystore file with a new one.

In case you do want to submit the app with a new keystore file, then you’ll have to change the package name of the app which leads you back to 0 reviews 🙁.

Here is an example of our signingConfigs in build.gradle file.

In order to install the app on a device, you need to generate a signed APK by running the following command from root directory

cd android && ./gradlew assembleRelease

Once you have the signed APK, you can send it to your friends and they’ll be able to install and use the app.

And by the way, the application will be in production mode, so if you are using the app in production mode for the first time, you’ll notice performance improvements vs development mode.

You will need Google Developers account which you can get for $25 (one time purchase fee) for submitting the app to the Google Play store.

Read more about that process here .

iOS

Unlike Android, there are several steps that you need to do in order to run your app on a real device.

The first, and most important step, is to get an Apple Developers account which is needed for creating applications on their development portal and creating necessary certificates and provisioning profiles. An account costs $99 per year .

Now that you have your Apple Developers account (it may take them some time to confirm your account, specially if you are registering on behalf of a company), you should be able to create a new application using this link .

Once you have chosen your App ID in the creation process, don’t change it afterwards because you’ll have to reissue all certificates, provisioning profiles, and store entry (say bye bye to the name!). That would definitely be a waste of time, and this App ID is usually hidden from users, so you should give it a unique codename or later on you will have to change it.

Now that you got your App ID registered, you can create Certificates which are usually used by third party services, such as Push notifications. What interests us in this section is the creation of Provisioning profiles.

A provisioning profile is a collection of digital entities that uniquely ties developers and devices to an authorized iPhone Development Team and enables a device to be used for testing.

In short, the only way for you to test the application on a real device is either by publishing your app through the store or bundling it with a correct provisioning profile during the archive process.

When creating a provisioning profile, you need to choose an Ad Hoc type profile under Distribution so you can install the app on test devices.

Then you’ll need to choose which test devices will be added to the Provisioning Profile, after that you can download and use the profile.

There is a limitation of 100 devices that can be added as testing devices. In order to add one, all you need is an UDID (Unique Device Identifier) of the device and a name for the device.

This site explains how to get an UDID from a device.

My advice is to ask your testers to copy and paste the UDID they get with the method mentioned above. There is a good chance they’ll provide a screenshot, so you’ll have to go through the pain of manually typing the UDID which is a nightmare.

Shoutout to you dear reader, if you know some good tools that can help in development, please let us know.

So far I only ran into one type of development tool, and that’s the inspector for React Native, what allows you to have the same development experience as you’d have on the web.

React Native Debugger

React Native Debugger is a standalone app that you run on your machine in order to debug your application.

One of the functionalities that this tool offers, that I cannot live without, is the option to inspect network.

Not sure if you tried to do this on the device or simulator, but it’s such a pain since the interface is so tiny and your network requests get spammed by the debugger requests. When you open the React Native Debugger, just right click on it and press Enable Network Inspector.

Be aware of one thing, you cannot upload files while Network Inspector is enabled, I’ve lost a full day on this issue. ^.^ Read about the issue here .

Other good functionality, which you can see from the screenshot shown above is the option to inspect your React Native elements, and adjust stylesheet properties. We know that React Native is fast at applying updates, but why stop there, having the same experience on the web when it comes to inspecting and adjusting style on the element is the way to go!

Last but not least, Redux inspector!

Configuration

In order to have Redux inspector to work, here is how your store file should look like.

Handling different environments

React Native on it’s own doesn’t provide support for Environment variables which is a crucial functionality in professional development. Depending on the Environment (Development, Staging/Testing, Production) you’ll be using different API keys, databases, analytics keys and such.

There are several modules on npm that allow you to use environment variables, but not all of them allow you to use variables in JavaScript, Java and Objective-C code.

Usually, all your code will be in the JavaScript part of your application, but if you use functionalities such as Push Notifications, Over the Air updates, crash services, etc. you’ll need to make adjustments in Native code.

So far we’ve been using React Native Config and we love it.

All you have to do is to install the package, and add .env file to the root of your directory. Next time you install the application, it’ll run a script that reads values from .env file, or you can specify .env file location in ENVFILE variable. I tested this module on several Continuous Integration services and it works like a charm!

My advice for you is to add .env file to your .gitignore file and provide an .env.example file which should inform developer of environment values that are used within a project — Environment values/files can be shared between developers, or you can have a separate environment for each developer.

When it comes to deploying applications, Continuous Integration and Deployment services should have their own environment values, so that the developer doesn’t have to worry if he is using correct environment values when releasing an app.

Tips

In case you have some tips, drop them in the comments and I’ll update the article. ;)

A Babel plugin to add a new resolver for your modules when compiling your code using Babel. This plugin allows you to add new “root” directories that contain your modules. It also allows you to setup a custom alias for directories, specific files, or even other npm modules.

Check the code snippet below

// Use this: import MyUtilFn from 'utils/MyUtilFn'; // Instead of that: import MyUtilFn from '../../../../utils/MyUtilFn';

SOLD! Right?

Module resolver allows us to write absolute paths using aliases, instead of writing relative paths which can be a pain at some points because you need to be aware of your component/file depth and location of the file you’d like to import. With absolute path imports, all you need to know is the location of the file you want to import, and you can even simplify that by providing an alias.

Check our babel configuration below!

ran into one issue, I had to start react native packager with — reset-cache, otherwise it throws an error. A simple npm/yarn script fixes it:

npm run start — — reset-cache

However, it seems like they have fixed this issue in the latest v3.0 beta releases, been using it for the last few days and it seems to work without any issue!

React Native communities

Here are few links to React Native communities with thousands of people where you can participate in discussions, read related news and articles, ask for help and such things:

Next articles will cover topics such as:

Navigation

Continuous integration and deployment

Dealing with images in application

Handling keyboard and views with forms

Over the Air updates

etc.