The complete guide to env variable in react native
Tags: reactnative, typescript
Published: 2023-03-21 15:44:28

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](https://12factor.net/) 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](https://github.com/alvessteve/react-native-env)_

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

[`process`](https://nodejs.org/dist/latest-v8.x/docs/api/process.html) is a module exclusive to NodeJS. However, React Native doesn't 
use Node to run its JS bundle but relies on the [`Hermes engine`](https://hermesengine.dev/). 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:
- [react-native-dotenv](https://github.com/goatandsheep/react-native-dotenv)
- [react-native-config](https://github.com/luggit/react-native-config)

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

> NB: some [ressources](https://stackoverflow.com/questions/33117227/setting-environment-variable-in-react-native) advices to use 
> [this babel plugin](https://www.npmjs.com/package/babel-plugin-transform-inline-environment-variables)
> 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:

```javascript
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.

```typescript
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:

```typescript
import Config from "react-native-config";

Config.FEATURE_ENABLED; // true
```

and on the native side:

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

on the gradle configuration:
```groovy
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](https://github.com/goatandsheep/react-native-dotenv) and [react-native-config](https://github.com/luggit/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.