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.
Top comments (3)
Thanks for the article. This should be added to the RN official docs.
FYI: react-native-dotenv has been archived and unsupported since 2020.
Just learned I was looking at the wrong repo. zetachang's version is archived, but another repo with the same name (no, not confusing at all) react-native-dotenv is under active maintenance.