I Do Not Like Dotenv

Jan 25, 2019 06:29 · 607 words · 3 minute read Rants Libraries

… as a library dependency.

So there’s this thing that I see used time and time again in all the enterprise-y projects I seem to touch. I’d say at least for the past 5 years. It’s a thing called dotenv, and I can’t say I like it very much. (Oh my, so original, didn’t see that coming, not at all in your title, not at all, what a turn of events)

But wait there’s more

The reason I don’t like it is people tend to import it as a library in their code, all the while running said code inside a Docker image, and locally using docker-compose to do so. FIRST A BIT OF HISTORY and crazy old man rant.

Dotenv is implemented in many different languages, sometimes in many different libraries within one language’s ecosystem. The point is to store your environment vars in a file. Were I a betting man, I’d wage it comes from the 12-Factor App. Let’s be clear, up to this point, I have no real problem with this. It’s fairly useful not to pollute your local everyday environment with tons of environment vars, it’s easier to clean up if you change values (although I’d say that part is debatable). With today’s processing power, on your dev environment, you can probably get away with setting a few tens of environment variables in your environment before it becomes a real issue, one would think.

Why you don’t need dotenv as a library

Around the same time I’ve seen dotenv appear, Docker was becoming a real actual thing with Actual Traction™. There was this tool, docker-compose, floating around, allowing you to do real clever things with Docker images, setting up whole interdependant environments, including setting up environment variables for the images you started.

It also allows you to specify an env_file option which… takes a file in the dotenv format. Wait wait, even better: If you go and read the docs, you even learn that it is equivalent to Docker’s –env-file option. Yup, that’s right; you can straight up feed dotenv files to Docker. Removed that library already? sigh

If memory serves, this is also a bit before Kubernetes really took off. Wikipedia tells me the initial release was 4 years ago at time of writing (2015! Time flies!). That being said, it’s been over two years since I last worked in a place that didn’t deploy all the things to k8s. I learned enough of it to shoot off my own foot if required, and I know for a fact that you can set environment variables in k8s.

This all leading to my point: I don’t see why you’d pull a third party library in to load environment variables in your process, when there’s literally a gazillion things in your environments, both local and otherwise, capable of doing the exact same thing at no extra complexity cost. It literally is a three-line shellscript for you to grab a dotenv-formatted file and export the vars from there to a subprocess of your choice.

And if that’s still not enough for you, use a dotenv loader program like this one and be done with it already: https://github.com/joho/godotenv#installation <– Careful, pick the “bin command” option, not library.

Addendum

A friend pointed out that it is weird that I end the article with a link to a repository that provides both a dotenv library and dotenv binary, so here is my homegrown garbage “good-enough” bash solution that I personally use.

#! /bin/bash

grep '^[A-Za-z_]\+=' $1 | sed 's/^/export /' > /tmp/dotenvloader
source /tmp/dotenvloader
shift
if [[ "$#" -gt 0 ]]; then
    exec "$@" && exit
fi
bash