Reading Environment Variables in Node.js
Introduction
Ever wondered how to manage sensitive data like API keys, database credentials or configuration settings in your Node.js applications? The answer lies with environment variables. This Byte will give a brief intro to environment variables, why they are important, and then we'll explore how to read them in Node.js using different methods.
What are Environment Variables
Environment variables are name-value pairs that can affect the way running processes behave on a computer. They exist in every operating system, and are used to make certain information globally available to all running processes. In the context of Node.js, environment variables are primarily used to set process-level variables that are global to the application.
console.log(process.env);
Running the above code in Node.js will output an object containing your environment variables. It might look something like this:
{
TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'username',
PATH: '...',
PWD: '/',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/home/username',
LOGNAME: 'username',
_: '/usr/local/bin/node'
}
We'll look at process.env
more later in this Byte.
Why Use Environment Variables
But why should you use environment variables in your Node.js applications? Well, there are several reasons:
- Security: Environment variables allow you to hide or separate sensitive data from your application code. This is particularly useful when you're dealing with passwords, API keys, or any other sensitive data that you don't want to expose in your code. Keeping these keys separate from your code means it won't get checked into a Git repo and then shared with everyone.
Safeguard your keys! Accidentally checking in AWS access keys into public Git repos is so common that there are bots that watch for these keys. When found, the bots will set up crypto mining software in your AWS account, potentially costing you thousands of dollars in compute costs.
-
Portability: With environment variables, you can configure your application to work in different environments. This is useful when you need to switch between different settings for development, testing, and production environments - or even between operating systems!
-
Ease of use: Environment variables are easy to use and can be accessed from anywhere in your application. They provide a simple way to store and retrieve configuration settings and commonly used throughout all types of software.
How to Read Environment Variables in Node.js
There are two main ways to read environment variables in Node.js: using the process.env
global object, and using the dotenv
module.
Using process.env
The process.env
global object is a simple way to access your environment variables. It's available globally in your application, and you don't need to import any additional modules to use it.
Here's an example of how you can read an environment variable using process.env
:
console.log(process.env.USER);
Running this code will output the value of the USER
environment variable:
'username'
However, while process.env
is simple and easy to use, it has its limitations. For instance, it doesn't provide a way to load variables from a file, which you'd then have to set by specifying them on the command that launches your app. But what if you have lots of variables to set? This is where the dotenv
module comes in handy.
Note: It's a good practice to prefix your custom environment variables with a specific keyword related to your app or company. This helps avoid potential conflicts with system-level environment variables.
Using dotenv Module
The dotenv module is a third-party module that allows you to load environment variables from a .env
file into process.env
. This is particularly useful when you have a large number of environment variables, or when you want to easily switch between different environments (i.e. dev, staging, prod, etc).
Here's how you can use dotenv
to read environment variables:
First, install the dotenv
module using npm:
$ npm install dotenv
Next, create a .env
file in the root of your project and add some variables:
DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3
Finally, you can load the variables from the .env
file into process.env
using dotenv
:
require('dotenv').config();
console.log(process.env.DB_HOST);
console.log(process.env.DB_USER);
console.log(process.env.DB_PASS);
Running this code will output the values of the DB_HOST
, DB_USER
, and DB_PASS
environment variables:
'localhost'
'root'
's1mpl3'
And there you have it! You now know how to read environment variables in Node.js using both process.env
and the dotenv
module.
Common Errors and How to Fix Them
While reading environment variables in Node.js is generally pretty easy, and thus fairly error-free, you might encounter a few hiccups along the way. Here are a couple of common issues to look out for:
-
undefined
values: Ifprocess.env.YOUR_VARIABLE
returnsundefined
, it means the environment variableYOUR_VARIABLE
wasn't set before the process started. Make sure the variable is set and exported in your environment, or loaded from the.env
file. Anundefined
value could be an indicator of another problem. -
Dotenv doesn't load variables: If you're using
dotenv
and your variables aren't loaded, make sure the.env
file is in your project root and that you're callingdotenv.config()
before trying to access the variables.If your env file is not being loaded because it has a different name, you can either rename it to the standard
.env
name or use thepath
setting to specify a different name:require('dotenv').config({ path: './.env-dev' })
Note: When using dotenv, remember that it doesn't overwrite existing environment variables. So if you have an environment variable set in your environment and a different value for the same variable in your .env
file, process.env
will contain the value from your environment.
Use Cases
Environment variables are used in tons of software projects and have lots of use-cases, a few of which we'll touch on here.
Storing Sensitive Information
Consider a scenario: You're working on a project that interacts with a database. Naturally, you'll need to store the database credentials. But, is it a good idea to hardcode these values into your Node.js application? Nope!
Storing sensitive information such as database credentials, API keys, or any other secret data directly in your code can lead to serious security issues. This data can be easily exposed if your codebase is publicly accessible, say, on a GitHub repository.
This is where environment variables come in handy. By storing sensitive information in environment variables, you're ensuring that this data isn't exposed in your codebase.
Note: Always remember to add your .env
file to your .gitignore
file to prevent it from being tracked by Git and exposed on platforms like GitHub.
Configuration Management
Ever wondered how you can manage different configurations for development, testing, and production environments in your Node.js application? Environment variables to the rescue, again!
Managing configurations with environment variables is a common practice. It allows you to define different values for your variables depending on the environment your application is running in.
For instance, you might want to use a different database for development and production. You can manage this by setting an environment variable, say DB_HOST
. In your development environment, DB_HOST
can be set to the URL of your development database. Similarly, in production, DB_HOST
can point to your production database.
This way, you can easily switch between different configurations without changing any code in your application.
Conclusion
In this Byte, we've explored the importance of environment variables in Node.js applications. We've seen how they can help secure sensitive data and manage different configurations for various environments.
But, there's more to environment variables than just storing secrets and managing configurations. They can also be used for feature flagging, setting application-level constants, and more.