With the recent release of version 20.6.0, Node.js now has built-in support for
.env files. You can now load environment variables from a
.env file into
process.env in your Node.js application completely dependency-free.
.env file is now as simple as:
node --env-file .env
What is .env?
.env files are used to configure environment variables that will be present within a running application. The idea comes from the Twelve-Factor App methodology, which says to store everything that is likely to vary between deploys (e.g. dev, staging, production) in the environment.
Config should not be a part of your application code and should not be checked-in to version control. Things like API credentials, or other secrets, should be stored separately and loaded in the environment in which they are needed. A
.env file lets you manage your config for applications where it isn’t practical to set variables in the environment, like your development machine or CI.
There are libraries in many different languages that support using a
.env file to load variables into the environment, they are usually called “dotenv”, and the Node.js dotenv is no different. But now, Node.js itself supports this behaviour.
How do you use .env in Node.js?
.env file looks like this:
PASSWORD=supersecret API_KEY=84de8263ccad4d3dabba0754e3c68b7a # .env files can have comments too
By convention you would save this as
.env in the root of your project, though you can call it whatever you want.
You can then set the variables in the file as environment variables by starting Node.js with the
--env-file flag pointing to your
.env file. When loaded, the variables are available as properties of
$ node --env-file .env Welcome to Node.js v20.6.0. Type ".help" for more information. > console.log(process.env.PASSWORD) supersecret undefined > console.log(process.env.API_KEY) 84de8263ccad4d3dabba0754e3c68b7a undefined
Support right now is fairly basic compared to dotenv. For example:
- You cannot currently use multiline values
- You cannot use variable expansion
- You can only specify one file at a time. Node.js will only use the last flag passed, so in the following example, only the variables from
.env.developmentwill be used:
node --env-file .env --env-file .env.development
There is more work to be done, and some of these features may be added. You can follow the discussion on GitHub here.
As of the 20.6.0 release, the documentation says, “If the same variable is defined in the environment and in the file, the value from the environment takes precedence.” This is the way that all dotenv packages work by default. However, that is not currently true of Node.js’s implementation and variables in the
.env file will override the environment. I have an open pull request to correct this.
Benefits to Node.js’s implementation
Even though this implementation is missing some features, it has some benefits over using a third-party package. Node.js loads and parses the
.env file as it is starting up, so you can include environment variables that configure Node.js itself, like
So, you can have an
.env file that looks like this:
Then, when you run
node --env-file=.env the process will run without emitting warnings and it will activate the inspector on the IP address
Note: you cannot put
NODE_OPTIONS="--env-file .env in your
.env file. It is disallowed to avoid inifinite loops.
Node.js just keeps improving
Go try out Node.js version 20.6.0! Version 20 has brought new features, like a stable test runner, mock timers, and now
.env file support, as well as many other upgrades, fixes and improvements. Version 20 becomes the active LTS version of Node.js in October, so now is a good time to test these new features out and start considering upgrading your application to take advantage.