Node native .env support
Starting in Node 20.6.0 there is built-in support for loading environment variables from a .env
file into process.env as recommended in The Twelve-Factor App methodology.
In this post we'll talk about .env, what it is, why use it, and how it works in Node.
What is .env file and why use it? #
An .env
file contains all configuration files for your application like passwords, API keys and other potentially sensitive information.
The idea comes from the Twelve-Factor App Methodology that suggest that we store config in environment variables.
These environment variables are easy to change and they won't be checked in to version control. They are also language-neutral. They should also be OS-neutral but Windows may not always work like Linux and Mac do.
You can also create different .env
configurations for your development, testing and production environments.
There are situations where we can't set Environment Variables manually like in Github Actions or other CI/CD pipelines. That's where .env
files come in handy. The file has all the values for the specific environment you're working with.
An example .env
file looks like this:
PASSWORD=supersecret
API_KEY=84de8263ccad4d3dabba0754e3c68b7a
As long as you don't check the .env
files into your source code respository, the information will remain private and your app will be more secure.
How does it work #
Until now we've had to use external packages like dotenv to work with .env
files in Node.
Native support means that we don't need these third-party tools. We can load the .env
file directly into Node by passig the --env-file
flag with the name of the .env
file (named .env
by default but can be any name you want).
node --env-file .env
Once the file is loaded you can use the properties as any other property in node.process.env
.
Using this .env
file, called .env
:
PASSWORD=supersecret
API_KEY=84de8263ccad4d3dabba0754e3c68b7a
We can load it using the --env-file
flag, as discussed earlier
node --env-file .env
And then query the variables in the file just like you would query any other environment variables.
Note that loading the .env
file will also work on the Node REPL, as shown below using Node 20.7.0.
node --env-file .env
Welcome to Node.js v20.7.0.
Type ".help" for more information.
> console.log(process.env.PASSWORD)
supersecret
undefined
> console.log(process.env.API_KEY)
84de8263ccad4d3dabba0754e3c68b7a
undefined
>
In Node 20.7.0 (the latest version as I write this), you can provide load multiple .env
files. The second and subsequent .env
files will override properties with the same name.
Caveats #
Node's native .env implementation lacks some features available in the dotenv package like:
- You cannot currently use multiline values
- You cannot use variable expansion
Despite the lack of some features, Node's native implementation has an advantage over third-party packages: Since Node.js loads and parses the .env
file as it is starting up, 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.
To avoid infinite loops, you cannot put NODE_OPTIONS="--env-file .env
in your .env
file.