The complete guide to environment variables in react native

Photo by Joan Gamell on Unsplash

The complete guide to environment variables in react native

Environment variables are very useful in software engineering. It allows you to gain more flexibility on your configuration, bring feature flags, avoid duplicates and be 12 factor compliant. For instance, you can declare several domain for your backend api and with just a few lines of code you switch. Usually, in the frontend world, dealing with env variables is pretty straightforward. However, in the React Native world, there is a few differences that can be confusing for any newcomer. Thus, the aim of this article is to help you clear away the deadwood from it.

Nota Bene: the example shown can be accessed here

What ?! no need to write an article about that just use process.env

process is a module exclusive to NodeJS. However, React Native doesn't use Node to run its JS bundle but relies on the Hermes engine. Unfortunately, hermes doesn't embark the process module or a way to emulate it.

However, one exception exists: process.env.NODE_ENV have been implemented for convenience purposes (it is like a standard).

That’s why we need to use a separate library or implement our custom one. Nowadays, The React Native ecosystem provide two popular alternatives:

Both share the same purpose but uses different strategies that we’ll explain right away.

NB: some ressources advices to use this babel plugin It doesn’t work on newer version of RN because the process.env doesn’t exist.

react-native-dotenv

react-native-dotenv is a babel plugin that let you inject your environment variable into your javascript environment. You declare it as a plugin in your .babelrc file and that's it ! Let us ding into and example.

here is our .env file:

FEATURE_ENABLED=true

and it can be accessed in our code like this:

import {FEATURE_ENABLED} from "@env"

console.log(FEATURE_ENABLED)

For typescript users, you’ll have to create a definition file env.d.ts to have code completion.

declare module '@env' {
    export const FEATURE_ENABLED: boolean;
}

As we can see, as it is a babel plugin, our variables are accessible ONLY in the JS part. So, if we want to have access within the native part, we’ll have to use another library the react-native-config

react-native-config

As said above, the specificity of this library is that it allows you to access your variables on both sides. They did that by parsing the .env files directly on the native sides and generating a map.

On the JS side, the use is similar as the previous lib:

import Config from "react-native-config";

Config.FEATURE_ENABLED; // true

and on the native side:

public Boolean isFeatureEnabled(){
   return BuildConfig.FEATURE_ENABLED;
}

on the gradle configuration:

defaultConfig {
    applicationId project.env.get("FEATURE_ENABLED")
}

As we can see, this library provides more possibilities. However, as it is implemented on the native side, it would require to cross the bridge if you want to access the value of an environment variable on the JS side, causing some performance issues if not dealt well or an unnecessary round trip. That’s why we recommend this library if you are sure that you would need an access on the native side.

Conclusion

As we saw, there is a couple of choices to handle env variables in React Native. According to your needs, you would need one or another. Below lies a summary:

TL;DR

  • two librairies are mainly used: react-native-dotenv and react-native-config

  • both are easy to use and easy to configure

  • use react-native-dotenv if your variables are needed only in the JS part

  • use react-native-config if your variables are needed on both parts (native and JS).

  • process.env can't be used in the RN ecosystem as it does not run inside a NodeJS app but a Hermes engine one instead.