How to use .env files in Node.js with import syntax

By

Learn how to use a .env file in a Node.js project with ES modules import syntax by installing the dotenv package and calling dotenv.config() in your script.

~~~

To use a .env file in a Node.js project that uses ES modules import syntax, install the dotenv package and load it before anything reads process.env. Here’s how.

I assume you have a Node.js project set up to use ES modules, and you want to use a .env file to store a secret, like this:

PASSWORD=secret

And you want to have it available in your Node.js script.

Why do we need a package for this?

The .env file is a convention, not something Node loads automatically. When your script runs, process.env only contains the variables set in your shell. The dotenv package reads the .env file and copies its values into process.env.

Install it:

npm i dotenv

Then use this code:

import * as dotenv from 'dotenv'
dotenv.config()
console.log(process.env.PASSWORD) //secret

This assumes you use ES modules (if not, it’s as easy as adding "type": "module", in your package.json).

Watch out for import order

There’s a catch with ES modules. Imports are hoisted: every import statement runs before any other code in the file. If another module reads process.env at import time, it runs before your dotenv.config() call, and the variable is still undefined there.

The fix is the side-effect import:

import 'dotenv/config'
import { db } from './database.js'

dotenv/config calls config() for you the moment the module loads, so the variables are ready for everything imported after it. My advice is to use this form and put it as the first import of your entry file.

Recent Node.js versions can also load the file natively with node --env-file=.env app.js, if you’d rather skip the dependency.

Values are always strings

Everything in process.env is a string. If your .env file contains DEBUG=false, then process.env.DEBUG is the string 'false', which is truthy:

if (process.env.DEBUG) {
  //this runs even when DEBUG=false
}

Compare against the string instead: process.env.DEBUG === 'true'.

One last thing: add .env to your .gitignore. The whole point of the file is keeping secrets out of your code, so don’t commit it.

By the way, if you need to turn a .env file into JSON or YAML (or the other way around), I built a free env converter.

Tagged: Node.js · All topics
~~~

Related posts about node: