Various ways of handling environment variables in React and Node.js
Tags: react, javascript, codenewbie, node
Published: 2020-09-21 05:03:34

Using Environment variables is very important to keep your private information secure. 

It may contain your API keys or database credentials or any other private information. It's always recommended to use environment variables to keep the information secure and you should never write them directly in your code.

Also, you need to make sure that, you add the environment variables file name to your `.gitignore` file so it will not be added to your Git repository when you push the code to the repository.

Let's look at the various ways of using the environment variables

## Using Create React App

### with single .env file:

If you're using create-react-app, then to use environment variables in your application, you need to create a `.env` file in the root of your project with each variable name starting with `REACT_APP_`

Create React App will make sure, the variables declared in the `.env` file will be available in your application if you're naming it starting with `REACT_APP_`

For example, If your `.env` file looks like this:

```js
REACT_APP_CLIENT_ID=abcd2whdkd
REACT_APP_API_KEY=3edcb4f9dd472ds4b47914ddcfb1791e1e1ab
```

Then you can access the variables directly in your React application using `process.env.REACT_APP_CLIENT_ID` and `process.env.REACT_APP_API_KEY`

Demo: [https://codesandbox.io/s/env-vars-create-react-app-mr0rl](https://codesandbox.io/s/env-vars-create-react-app-mr0rl) 


### with multiple .env files:

If you're having multiple `.env` files like `.env.prod`, `.env.uat`, `.env.dev` for production, UAT, and development environment respectively then just using `REACT_APP_` for environment variable name will not work.

Suppose, you're using the firebase database in your application and your firebase configuration looks like this:

For the development environment:

```js
const config = {
  apiKey: 'AIdfSyCrjkjsdscbbW-pfOwebgYCyGvu_2kyFkNu_-jyg',
  authDomain: 'seventh-capsule-78932.firebaseapp.com',
  databaseURL: 'https://seventh-capsule-78932.firebaseio.com',
  projectId: 'seventh-capsule-78932',
  storageBucket: 'seventh-capsule-78932.appspot.com',
  messagingSenderId: '3471282249832',
  appId: '1:3472702963:web:38adfik223f24323fc3e876'
};
```

For the production environment:
```js
const config = {
  apiKey: 'AIzaSyCreZjsdsbbbW-pfOwebgYCyGvu_2kyFkNu_-jyg',
  authDomain: 'seventh-capsule-12345.firebaseapp.com',
  databaseURL: 'https://seventh-capsule-12345.firebaseio.com',
  projectId: 'seventh-capsule-12345',
  storageBucket: 'seventh-capsule-12345.appspot.com',
  messagingSenderId: '3479069249832',
  appId: '1:3477812963:web:38adfik223f92323fc3e876'
};
```

but you should not write this code directly in your application because anyone can just copy-paste the above configuration into their app and can manipulate your firebase data so Instead, you should create an environment variable for each property of the config object and use that.

If you create a `.env.prod` file for the production environment then it will look like this:

```js
REACT_APP_API_KEY=AIzaSyCreZjsdsbbbW-pfOwebgYCyGvu_2kyFkNu_-jyg
REACT_APP_AUTH_DOMAIN=seventh-capsule-12345.firebaseapp.com
REACT_APP_DATABASE_URL=https://seventh-capsule-12345.firebaseio.com
REACT_APP_PROJECT_ID=seventh-capsule-12345
REACT_APP_STORAGE_BUCKET=seventh-capsule-12345.appspot.com
REACT_APP_MESSAGING_SENDER_ID=3479069249832
REACT_APP_APP_ID=1:3477812963:web:38adfik223f92323fc3e876
```

and your `.env.dev` file will look like this:

```js
REACT_APP_API_KEY=AIdfSyCrjkjsdscbbW-pfOwebgYCyGvu_2kyFkNu_-jyg
REACT_APP_AUTH_DOMAIN=seventh-capsule-78932.firebaseapp.com
REACT_APP_DATABASE_URL=https://seventh-capsule-78932.firebaseio.com
REACT_APP_PROJECT_ID=seventh-capsule-78932
REACT_APP_STORAGE_BUCKET=seventh-capsule-78932.appspot.com
REACT_APP_MESSAGING_SENDER_ID=3471282249832
REACT_APP_APP_ID=1:3472702963:web:38adfik223f24323fc3e876
```

To access these environment-specific files, install the `env-cmd` npm package using the following command:

```js
yarn add env-cmd 

OR

npm install env-cmd 
```

and then change the `package.json` file `script` section to use `env-cmd` command

```js
"scripts": {
 "start": "env-cmd -f .env.dev react-scripts start",
 "start-prod": "env-cmd -f .env.prod react-scripts start",
 "build": "react-scripts build",
 "test": "react-scripts test --env=jsdom",
 "eject": "react-scripts eject"
},
```

So now, when you run the `yarn start` or `npm start` command from the terminal, it will load the environment variables from the `.env.dev` file and when you run the `yarn start-prod` or `npm start-prod` command from the terminal, it will load the environment variables from the `.env.prod` file.

You can even create a single `.env-cmdrc`, If you're using `env-cmd` npm package and declare all environment variables in a single file as a JSON object like this:

```js
{
    "dev": {
        "REACT_APP_API_KEY": "AIdfSyCrjkjsdscbbW-pfOwebgYCyGvu_2kyFkNu_-jyg",
        "REACT_APP_AUTH_DOMAIN": "seventh-capsule-78932.firebaseapp.com",
        "REACT_APP_DATABASE_URL": "https://seventh-capsule-78932.firebaseio.com",
        "REACT_APP_PROJECT_ID": "seventh-capsule-78932",
        "REACT_APP_STORAGE_BUCKET": "seventh-capsule-78932.appspot.com",
        "REACT_APP_MESSAGING_SENDER_ID": "3471282249832",
        "REACT_APP_APP_ID": "1:3472702963:web:38adfik223f24323fc3e876"
    },
    "prod": {
       "REACT_APP_API_KEY": "AIzaSyCreZjsdsbbbW-pfOwebgYCyGvu_2kyFkNu_-jyg",
        "REACT_APP_AUTH_DOMAIN": "seventh-capsule-12345.firebaseapp.com",
        "REACT_APP_DATABASE_URL": "https://seventh-capsule-12345.firebaseio.com",
        "REACT_APP_PROJECT_ID": "seventh-capsule-12345",
        "REACT_APP_STORAGE_BUCKET": "seventh-capsule-12345.appspot.com",
        "REACT_APP_MESSAGING_SENDER_ID": "3479069249832",
        "REACT_APP_APP_ID": "1:3477812963:web:38adfik223f92323fc3e876"
    }
}
```

and then use the -e flag for specifying which environment to refer in your `package.json` file like this:

```js
"scripts": {
 "start": "env-cmd -e dev react-scripts start",
 "start-prod": "env-cmd -e prod react-scripts start",
 "build": "react-scripts build",
 "test": "react-scripts test --env=jsdom",
 "eject": "react-scripts eject"
},
```

So now, when you run the `yarn start` or `npm start` command from the terminal, it will load the dev specific environment variables from the `.env-cmdrc` file and when you run the `yarn start-prod` or `npm start-prod` command from the terminal, it will load the prod specific environment variables from the `.env-cmdrc` file.

---

## Using Node.js

### with multiple .env files:

If you're using Node.js then you can use the same `env-cmd` npm package for accessing environment variables and changing the scripts in the `package.json` file as shown below

```js
"scripts": {
 "start": "env-cmd -f .env.dev node index.js",
 "start-prod": "env-cmd -f .env.prod node index.js"
},
```

If you want to run the `env-cmd` command directly from the terminal instead of the `yarn start` command, then you need to use the complete path of the `env-cmd` package like this:

```js
./node_modules/.bin/env-cmd -f .env.dev node index.js 

AND

./node_modules/.bin/env-cmd -f .env.prod node index.js
```

### with single .env file:

If you're having a single `.env` file then you can still use the `env-cmd` npm package but If you don't want to add `env-cmd` to the `package.json`, then you can install the `dotenv` npm package using the following command:

```js
yarn add dotenv

OR

npm install dotenv
```

and then inside the main Node.js file use the `config` method of the `dotenv` package like this:

```js
// index.js file

require('dotenv').config();

const API_URL = process.env.API_URL;
console.log(API_URL); // http://localhost:5000
```

If your `.env` file looks like this:

```js
API_URL=http://localhost:5000
```

Then to execute the file, you just need to run the following command from the terminal:

```js
node index.js
```

or add this command in your `scripts` section of the package.json file.

> This is my preferred way, If I don't require separate `.env` files as by just adding a call to the `config` method, the environment variables are available inside the `index.js` file and also available to all the files imported inside the `index.js` file after the `config` method call.

As we're not pushing the `.env` files to GitHub, to use the environment variables in your application deployed to production you need to add the environment variables from the UI in the deploy section provided by the hosting provider.

All the hosting providers provide an option to add environment variables from the UI.

For example, If you're using Netlify for deploying the application, then you need to go to Site settings => Build & deploy and scroll a bit, you will see an option to add environment variables as shown below

![Environment Variables](https://gist.github.com/myogeshchavan97/e0be7fc4c838544e2d00afeb3a82ae10/raw/07e9ff4529c1ea9078c812aeffa1b6ecc0da7f4d/env_vars.png)

> Make sure, you re-deploy your site after adding the environment variables so your application will use those newly added environment variables.

**Don't forget to subscribe to get my weekly newsletter with amazing tips, tricks and articles directly in your inbox [here](https://yogeshchavan.dev).**

[<img src="https://cdn.buymeacoffee.com/buttons/default-yellow.png" >](https://www.buymeacoffee.com/myogeshchavan97)