Environment variables are essential for configuring your Node.js applications, allowing you to tailor settings for different environments like development, testing, and production. While you can set environment variables directly in your system or terminal, a more elegant and organized approach is to use a .env file. This file allows you to store all your environment variables in one central location, keeping them separate from your code and making it easy to manage different configurations.
In this comprehensive guide, we’ll delve into the world of environment variables in Node.js, explore the role of the popular dotenv
package, and uncover how to use it effectively. We’ll also explore the native way of accessing environment variables in Node.js 20+ using ESM (EcmaScript Modules). Let’s get started!
Table of contents #
Introduction #
Imagine you’re building a Node.js application that needs to connect to a database. You’ll need to store the database credentials, such as the host, username, password, and database name, somewhere. Hardcoding these credentials directly into your code is a security risk and makes managing different configurations for different environments difficult.
That’s where environment variables come to the rescue. You can store sensitive information like API keys, database credentials, and other configuration settings as environment variables, keeping them separate from your codebase. This enhances security and makes it easier to deploy your application to different environments with different configurations.
A .env file is a simple text file that stores your environment variables in a key-value format. It’s a widely adopted convention in the Node.js ecosystem for managing environment variables, and there’s a popular NPM package called dotenv
that makes it easy to load these variables into your application. It also helps you achieve the config part of the 12-factor app. The 12-factor app’s config factor states, “requires strict separation of config from code. Config varies substantially across deploys, code does not.”
Prerequisites #
Before we dive into the code and explore how to use environment variables from a .env file, ensure you have the following prerequisites:
- Node.js 20 or later installed: We’ll be using the latest features of Node.js, so having a recent version installed is essential. You can check your Node.js version by running
node --version
in your terminal. - A basic understanding of Node.js and NPM: You should be familiar with running Node.js scripts and installing NPM packages using the
npm install
command. - Basic knowledge of JavaScript Modules: This guide will use ESM imports. This is the new standard for JavaScript modules, and it’s supported in Node.js 14 and above.
In the subsequent section, you will learn how to get environment variables using the dotenv
package.
Get environment variables using dotenv #
dotenv is a zero-dependency module that loads environment variables from a .env
file into process.env
. It’s a simple and convenient way to manage your environment variables, keeping them separate from your code and making deploying your application to different environments easier.
Installing dotenv #
To get started with dotenv
, you need to install it first. You can install it using the following command in your terminal:
npm install dotenv
This command will install the dotenv
package from the NPM registry and add it to your project’s package.json
file as a dependency. At the time of writing dotenv
is at version 16.4.5.
Creating a .env file #
After you have installed the dotenv
package, you can create a .env
file in the root directory of your project. This file will contain all your environment variables. The format of the .env
file is simple. Each line represents an environment variable, with the key and value separated by an equal sign (=
). For example:
DATABASE_NAME=quotes
DATABASE_USER=quotes_user
Loading environment variables #
To load the environment variables from your .env
file into process.env
, you need to call the config
method from the dotenv
module. This should be done at the very start of your application before any other code is executed. A common place to call the config method is in your application’s entry point, which is usually index.js
or app.js
. For instance:
import 'dotenv/config';const dbName = process.env.DATABASE_NAME;
const dbUser = process.env.DATABASE_USER;
console.log(`Database name is ${dbName} and database username is ${dbUser}`);
In the above code example, the dotenv/config
import call loads the environment variables from the .env
file into process.env
. Then, you add two constants, dbName
and dbUser
, to get the relevant environment variables and show them on the console with console.log
. If it was a real application, like an Express.js app, you would have used these variables to instantiate the connection to a database.
When you run the above index.js
file with node index.js
and the relevant .env
file it will show the following output:
If you want to use a different filename than .env
. You can import only the dotenv
module with import dotenv from 'dotenv';
, you can use a custom .env
file (not .env
), you can pass in the path to the file as an argument to the config
method like the below:
dotenv.config({ path: './.env.example' });
Another useful way of using dotenv
without any import or require is to pass it in the node command. For instance for a file named index-no-imports.js
which as the below contents with the same .env
file:
const dbName = process.env.DATABASE_NAME;
const dbUser = process.env.DATABASE_USER;
console.log(`Database name is ${dbName} and database user is ${dbUser}`);
You can acces the environment variable by executing:
node --require dotenv/config index-no-imports.js
Dotenv has a small ecosystem around it, you can learn more by reading it’s Readme file. There is dotenvx, you can encrypt and decrypt your environment variables, and dotenv-valut
too. It is supported by companies like Warp, WorkOs and Alloy Automation. It also has a YouTube channel and a video explaining how to use it. There are lots of official examples using it from projects like Next.js to express.
In the next section, you will learn about the native way of accessing environment variables in Node.js 20+.
Get environment variables natively Node 20+ #
From Node.js 20+, there is a native way to access environment variables without the
need to install a NPM package like dotenv.
From Node 20.6.0, one of the most notable changes is the built-in support for .env files
Using –env file in node cli #
With the same .env
file and the index-no-imports.js
file from the above example. You can use the environment variales from the .env
file in any js
file with the following command:
node --env-file .env index-no-imports.js
It will result in:
Which is exactly the same as the above output without the need to import dotenv
in the file or in the command line. This is possible from Node 20.6.0 as it added built-in support for .env files.
You can update your .env
file and run the code again and it will pick up the updated
environment variable. This is how you can access environment variables withimport.meta.env
in Node.js 20+. You can use nodemon to restart your applications when a .js
file changes or even when a .env
file changes with the correct watches.
For your reference, you can find the code examples in this GitHub repository.
Dotenv is still popular #
Given that Node.js 20+ has provided a native way to access environment variables since Sep 2023 (more than a year from when this blog post was written), you might be wondering why to bother with dotenv? It’s a valid question with a valid answer:dotenv
is still the most popular package for getting environment variables from a .env file.
With over 45 million downloads per week as of Nov 2023,
dotenv
is a battle-tested and widely used package in the Node.js ecosystem.
You can see a comparison of dotenv, node-env-file, and dot-env as per npm trends below:
As you can see, dotenv is the clear winner, with exponentially more weekly downloads than its competitor, node-env-file. Even though dot-env is a similar library, the downloads are minimal. dot-env
has not been updated in the past 11 years, though, whereas dotenv
is a very active project on GitHub.
Conclusion #
In this comprehensive guide, you have learned how to access environment variables from
a .env file in Node.js. You explored two methods, the first one using the popular dotenv package and the second one using the native --env-file
available in Node.js 20+. With the knowledge of both methods, you can now make an informed choice depending on your project’s needs.
If you are working on a new project, I recommend opting for the native
--env-file
method, as it’s part of Node.js and doesn’t need an external dependency. But if you are working on an existing project that already usesdotenv
, there’s no need to change.
In the end, both achieve the same goal of accessing environment variables from a .env file. Eventually you can move to the native way of accessing environment variables in Node.js 20+ as it’s part of the Node.js core and doesn’t need an external dependency. This will make your application more lightweight and reduce the number of dependencies.