Managing secrets and environmental variables in Node Js
Tags: node, webdev, javascript, beginners
Published: 2020-11-12 17:35:26

---
title: Managing secrets and environmental variables in Node Js
published: true
date: 2020-11-08 00:00:00 UTC
tags: nodejs, webdev, javascript, beginners
canonical_url: https://jsmates.com/blog/managing-secrets-and-env-variables-using-dotenv
---

Every code project requires to maintain secrets, configurations, and environment-specific variables.

Most common secrets are,

- Database connecting strings and passwords
- Email service account and passwords
- Third-party services API keys

Common environmental variables are,

- Port number
- Application environment (eg., NODE_ENV - test, development, production)

Other application-specific configurations like,

- Default email address
- Feature toggle variables

The first option is to manage it inside your code. But this won't work well if you keep your code in the remote repository (e.g, Github, GitLab, etc).

Also, this won't work if you are in a multi-developer environment. Every developer uses a different config that can't be hard-coded in the code.

This problem can be fixed in production by setting system environment variables. This variable can be accessed through `process.env` in your application.

But in development, you will have many applications on your computer. Most variables are the same for different applications. So you need to find a way to use this variable application-specific.

There is an awesome package to solve this issue in development. It is called as `dotenv`

`dotenv` helps to manage your environmental variables and configuration inside your application code.

Let's install `dotenv`,

```bash
npm install dotenv
```

Create a `.env` file in the root of the project.

```js
/*
  file: .env
*/

API_BASE_URL=http://localhost
PORT=8080
NODE_ENV=development
CLIENT_SECRET=xydwy10290askajs
```

Let's create a simple node Js application and use `dotenv` in `server.js` file,

```js
/*
  file: server.js
*/

const http = require('http');
const express = require('express');
// import dotenv package
const dotenv = require('dotenv');

// Use `.env` config when the NODE_ENV is other than production
if (process.env.NODE_ENV !== 'production') {
  dotenv.config();
}

const app = express();

// Root URL will serve all the process env values from the .env file
app.get('/', (req, res) => {
  res.json({
    node_env: process.env.NODE_ENV,
    port: process.env.PORT,
    api_root_url: process.env.API_BASE_URL,
    client_secret: process.env.CLIENT_SECRET,
    port_lowercase: process.env.port || null // Will be null, since env variables are case sensitive
  });
});

// Read port from PORT env variable or use 8080
const port = process.env.PORT || 8080;
const server = http.Server(app);

server.listen(port, () => {
  console.log(`Server listening on port: ${port}\n`);
});
```

Our code use `dotenv` for the environment other than `production`. It reads the `port` value and `NODE_ENV` from the `.env` file.

Start the server and check the root URL,
http://localhost:8080

This will be the result,

```json
{
  "node_env": "development",
  "port": "8080",
  "api_root_url": "http://localhost",
  "client_secret": "xydwy10290askajs",
  "port_lowercase": null
}
```

As you see, these env keys are case sensitive.

{% codesandbox dotenv-pdnnk %}