Skip to content

About

🗝️ Dotenv is a no-dep, pure Java module that loads environment variables from a .env file

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

🗝️ dotenv-js

Build Status All Contributors

A no-dependency JavaScript port of dotenv-java, itself a port of the Ruby dotenv project. Load environment variables from a .env file.

dotenv

Why dotenv?

Storing configuration in the environment is one of the tenets of a twelve-factor app. Anything that is likely to change between deployment environments–such as resource handles for databases or credentials for external services–should be extracted from the code into environment variables.

But it is not always practical to set environment variables on development machines or continuous integration servers where multiple projects are run. Dotenv load variables from a .env file into ENV when the environment is bootstrapped.

-- Brandon Keepers

Environment variables listed in the host environment override those in .env.

Use dotenv.get("...") instead of process.env[...].

Install

Requires Node 18 or greater.

npm install dotenv-js

Usage

Create a .env file in the root of your project

# formatted as key=value
MY_ENV_VAR1=some_value
MY_EVV_VAR2=some_value #some value comment
MULTI_LINE="some
multi line
value"
import { Dotenv } from "dotenv-js";

const dotenv = Dotenv.load();
dotenv.get("MY_ENV_VAR1");

Advanced Usage

Configure

Configure dotenv-js once in your application.

const dotenv = Dotenv.configure()
  .directory("./some/path")
  .ignoreIfMalformed()
  .ignoreIfMissing()
  .load();
Option Behavior
directory(path) the directory containing the .env file. Default ./
filename(name) the file name. Default .env
ignoreIfMalformed() skip malformed entries instead of throwing
ignoreIfMissing() return an empty environment instead of throwing when the file is absent
systemProperties() copy each entry into the system property table (see below)

Entries

dotenv.entries();                                   // host environment + .env
dotenv.entries(Dotenv.Filter.DECLARED_IN_ENV_FILE); // .env only
dotenv.get("KEY");                                  // null when absent
dotenv.get("KEY", "default value");

entries() returns a Set of DotenvEntry. It is unmodifiable: add, delete and clear throw UnsupportedOperationError.

API mapping

dotenv-java dotenv-js
Dotenv.configure() / Dotenv.load() same, static on Dotenv
Dotenv.Filter.DECLARED_IN_ENV_FILE same
entries() / entries(filter) entries(filter?)
get(key) / get(key, defaultValue) get(key, defaultValue?)
DotenvEntry#getKey() / #getValue() same, plus key / value getters
DotenvException same, with addSuppressed / getSuppressed
System.setProperty via systemProperties() setProperty / getProperty / clearProperty from dotenv-js
classpath lookup resource roots — addClasspathRoot(), setClasspathRoots(), DOTENV_CLASSPATH
Collections.unmodifiableSet UnmodifiableSet, throwing UnsupportedOperationError

Differences from the JVM original

The grammar, the precedence rules, the malformed-entry handling and the exception messages are identical; the port is verified by diffing what both implementations produce for the same fixtures. Three JVM concepts have no direct Node equivalent:

  • System properties. System.setProperty writes to a table separate from the host environment, which process.env is not. systemProperties() therefore writes to the table exported by src/systemProperties.js; read it with getProperty(key).
  • Classpath. A .env that is not found on the file system is looked up in an ordered list of resource roots — the analogue of a classpath lookup. Roots come from addClasspathRoot() / setClasspathRoots() and from the DOTENV_CLASSPATH environment variable (delimited like PATH); the working directory is searched last.
  • Unmodifiable collections. entries() returns a Set that throws on mutation rather than a Collections.unmodifiableSet.

java.lang.String#trim, String#substring and Files#readAllLines are reproduced in src/internal/strings.js rather than approximated with their JavaScript near-equivalents, which differ on Unicode whitespace and on out of range indices.

Examples

Test

npm test

FAQ

Q: Should I deploy a .env to e.g. production?

A: Tenet III of the 12 factor app methodology states "The twelve-factor app stores config in environment variables". Thus, it is not recommended to provide the .env file to such environments. dotenv, however, is super useful in e.g a local development environment as it enables a developer to manage the environment via a file which is more convenient.

Using dotenv in production would be cheating. This type of usage, however is an anti-pattern.

Q: Why should I use dotenv.get("MY_ENV_VAR") instead of process.env.MY_ENV_VAR

A: dotenv-js does not mutate process.env, so variables listed in .env cannot be retrieved through it. Reading through dotenv.get(...) also applies the host-environment-wins precedence rule.

Q: Can I retrieve environment variables as system properties?

A: Yes. Use the systemProperties option, then read them back with getProperty. Note that this table is deliberately separate from process.env, exactly as the JVM's system properties are separate from the host environment.

Q: Should I have multiple .env files?

A: No. We strongly recommend against having a "main" .env file and an "environment" .env file like .env.test. Your config should vary between deploys, and you should not be sharing values between environments.

In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as “environments”, but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime.

– The Twelve-Factor App

Q: Should I commit my .env file?

A: No. We strongly recommend against committing your .env file to version control. It should only include environment-specific values such as database passwords or API keys. Your production database should have a different password than your development database.

Q: What happens to environment variables that were already set?

A: dotenv-js will never modify any environment variables that have already been set. In particular, if there is a variable in your .env file which collides with one that already exists in your environment, then that variable will be skipped. This behavior allows you to override all .env configurations with a machine-specific environment, although it is not recommended.

Q: What about variable expansion in .env?

A: We haven't been presented with a compelling use case for expanding variables and believe it leads to env vars that are not "fully orthogonal" as The Twelve-Factor App outlines. Please open an issue if you have a compelling use case.

Note and reference: The FAQs present on motdotla's dotenv node project page are so well done that I've included those that are relevant in the FAQs above.

see CONTRIBUTING.md

License

see LICENSE (Apache 2.0)

Buy Me A Coffee

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Clement Cherlin
Clement Cherlin

💻 ⚠️
Alex Braga
Alex Braga

📖
Alexey Venderov
Alexey Venderov

💻
yassenb
yassenb

💻
Sidney Beekhoven
Sidney Beekhoven

💻 📖
Manoel Campos
Manoel Campos

💻 ⚠️ 🚇

This project follows the all-contributors specification. Contributions of any kind welcome!

About

🗝️ Dotenv is a no-dep, pure Java module that loads environment variables from a .env file

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages