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.
Loading an .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?
A .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 process.env
.
$ 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
Supported features
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.development
will 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.
Incorrect features
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 NODE_OPTIONS
.
So, you can have an .env
file that looks like this:
NODE_OPTIONS="--no-warnings --inspect=127.0.0.1:9229"
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 127.0.0.1:9229
.
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.