dotenvx - New generation dotenv tool

Posted at Jul 3, 2024

Hello there,

In this article, we will take a look at dotenvx which is created by the developer behind dotenv, @motdotla.

What was dotenv?

As you all know, we configure the programs we write to use environment variables to determine how they should work. To avoid having to redefine these environment variables every time we run the program, we use .env files.

Basically, the logic behind of the .env files is very simple; read the .env file on the path (by default in the process working directory) and make the variables defined in it available to our program as environment variables. This way, when we want to run our program, we don't have to define the variables we need one by one.

As you can see, .env is a concept and you can find different packages that implements this concept in every programming language. dotenvx brings a standard to this situation. Because until now, all .env processing tools have been available as external packages/libraries, whereas dotenvx is an executable program.

For example, you have installed the Y package in the X programming language to read the .env file. Now you need to use this Y package to include the code to read the .env file in your program. In dotenvx the situation is a bit different. To start our program, we first run dotenvx and give it our program as an argument. When dotenvx runs, it reads the environment variables from the .env file and passes them to your program.

Let's try it out!

Now let's go deeper through an example. First, let's install dotenvx on our system. You can install it using npm, brew, curl, docker or windows exe files. For more information, see install. I prefer to install with npm under my Debian system:

$ sudo npm i -g @dotenvx/dotenvx

added 100 packages in 11s

21 packages are looking for funding
  run `npm fund` for details

The dotenvx package is written in Node.js and is compatible with dotenv. This means that if you have written your program in Node.js and already use dotenv, you can use dotenvx as a drop-in replacement.

Since we will be using Go and Python in our example, I installed it globally, so I can run it with the dotenvx command. Now let's create a directory and an .env file:

$ mkdir dex
$ cd dex
$ touch .env

Now let's update the contents of our .env file:

NAME=John

Let's write a Go program that greets the environment variable NAME:

// main.go
package main

import (
	"fmt"
	"os"
)

func main() {
	name, exists := os.LookupEnv("NAME")

	if !exists {
		panic("NAME env variable couldn't find!")
	}

	fmt.Println("Hello", name)
}

Let's do the same example with Python:

# main.py
import os

name = os.environ['NAME'] # Throws an error if the key named NAME is not found.
print("Hello", name)

In both examples, our program hopes to find an environment variable named NAME when it is executed, and if it cannot find it, it terminates with an error.

If we wanted to be able to read .env files in both programs, we would need to install the python-dotenv package for Python and the godotenv package for Go. As you can guess, these are not the only dotenv packages for Python and Go.

So we will get rid of this package dependency by using dotnevx. All we need to do is run our program through dotenvx:

$ dotenvx run -- go run main.go
[dotenvx@1.5.0] injecting env (1) from .env
Hello John

For Python:

$ dotenvx run -- python3 main.py
[dotenvx@1.5.0] injecting env (1) from .env
Hello John

If you don't want to see the injecting... line, all you need to do is set the log level with the -l parameter:

$ dotenvx -l none run -- python3 main.py
Hello John

Thanks to dotenvx, we used a standardized method and now we can use features like encryption, multiple environment and variable expansion in our .env files. Also, as you can see, we haven't made any changes to our code!

Of course, this doesn't mean that dotenvx has no shortcomings. Since dotenvx is an executable, the people using your program need to install dotenvx alongside it or you need to distribute your program with dotenvx. If you distribute your program as a docker image, installing dotenvx in your image with curl seems to be the best solution.

For more information about dotenvx, please visit page. See you in the next article!

Footnotes