Setting environment variable in react-native?

React native does not have the concept of global variables. It enforces modular scope strictly, in order to promote component modularity and reusability.

Sometimes, though, you need components to be aware of their environment. In this case it's very simple to define an Environment module which components can then call to get environment variables, for example:

environment.js

var _Environments = {
    production:  {BASE_URL: '', API_KEY: ''},
    staging:     {BASE_URL: '', API_KEY: ''},
    development: {BASE_URL: '', API_KEY: ''},
}

function getEnvironment() {
    // Insert logic here to get the current platform (e.g. staging, production, etc)
    var platform = getPlatform()

    // ...now return the correct environment
    return _Environments[platform]
}

var Environment = getEnvironment()
module.exports = Environment

my-component.js

var Environment = require('./environment.js')

...somewhere in your code...
var url = Environment.BASE_URL

This creates a singleton environment which can be accessed from anywhere inside the scope of your app. You have to explicitly require(...) the module from any components that use Environment variables, but that is a good thing.


In my opinion the best option is to use react-native-config. It supports 12 factor.

I found this package extremely useful. You can set multiple environments, e.g. development, staging, production.

In case of Android, variables are available also in Java classes, gradle, AndroidManifest.xml etc. In case of iOS, variables are available also in Obj-C classes, Info.plist.

You just create files like

  • .env.development
  • .env.staging
  • .env.production

You fill these files with key, values like

API_URL=https://myapi.com
GOOGLE_MAPS_API_KEY=abcdefgh

and then just use it:

import Config from 'react-native-config'

Config.API_URL  // 'https://myapi.com'
Config.GOOGLE_MAPS_API_KEY  // 'abcdefgh'

If you want to use different environments, you basically set ENVFILE variable like this:

ENVFILE=.env.staging react-native run-android

or for assembling app for production (android in my case):

cd android && ENVFILE=.env.production ./gradlew assembleRelease

The simplest (not the best or ideal) solution I found was to use react-native-dotenv. You simply add the "react-native-dotenv" preset to your .babelrc file at the project root like so:

{
  "presets": ["react-native", "react-native-dotenv"]
}

Create a .env file and add properties:

echo "SOMETHING=anything" > .env

Then in your project (JS):

import { SOMETHING } from 'react-native-dotenv'
console.log(SOMETHING) // "anything"

Instead of hard-coding your app constants and doing a switch on the environment (I'll explain how to do that in a moment), I suggest using the twelve factor suggestion of having your build process define your BASE_URL and your API_KEY.

To answer how to expose your environment to react-native, I suggest using Babel's babel-plugin-transform-inline-environment-variables.

To get this working you need to download the plugin and then you will need to setup a .babelrc and it should look something like this:

{
  "presets": ["react-native"],
  "plugins": [
    "transform-inline-environment-variables"
  ]
}

And so if you transpile your react-native code by running API_KEY=my-app-id react-native bundle (or start, run-ios, or run-android) then all you have to do is have your code look like this:

const apiKey = process.env['API_KEY'];

And then Babel will replace that with:

const apiKey = 'my-app-id';

Tags:

React Native