dotenv vs config vs dotenv-safe vs dotenv-expand
Node.js 环境变量与配置管理方案
dotenvconfigdotenv-safedotenv-expand类似的npm包:

Node.js 环境变量与配置管理方案

configdotenvdotenv-expanddotenv-safe 都是 Node.js 生态中用于管理应用程序配置和环境变量的流行工具,但它们在设计理念、功能范围和适用场景上有显著差异。dotenv 提供最基础的 .env 文件加载能力;dotenv-expand 为其增加变量插值支持;dotenv-safe 强化了必需变量的校验机制;而 config 则是一个完整的结构化配置管理系统,支持多环境、嵌套配置和运行时覆盖。这些工具帮助开发者安全、灵活地管理不同环境下的应用设置,避免硬编码敏感信息。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
dotenv115,702,27720,35293.3 kB102 个月前BSD-2-Clause
config1,591,3056,424207 kB131 个月前MIT
dotenv-safe210,93877110.4 kB42 年前MIT
dotenv-expand01,05219.5 kB37 个月前BSD-2-Clause

Node.js 环境变量与配置管理方案深度对比:config vs dotenv vs dotenv-expand vs dotenv-safe

在现代前端和全栈 JavaScript 项目中,如何安全、灵活地管理配置信息(如 API 密钥、服务端点、功能开关等)是架构设计的关键一环。本文将深入剖析四个主流 npm 包 —— configdotenvdotenv-expanddotenv-safe —— 的核心机制、适用场景与技术取舍,帮助你在真实工程中做出明智选择。

📦 核心定位与使用方式

dotenv:基础环境变量加载器

dotenv 是最轻量、最广泛采用的方案。它从 .env 文件中读取键值对,并注入到 process.env 中。适合简单项目或作为其他配置方案的基础组件。

// .env
DB_HOST=localhost
API_KEY=12345

// app.js
require('dotenv').config();
console.log(process.env.DB_HOST); // 'localhost'

注意:dotenv 不会覆盖已存在的环境变量(例如通过命令行设置的 DB_HOST=prod 会优先于 .env 中的值)。

dotenv-expand:支持变量插值的扩展器

dotenv-expand 并非独立使用,而是配合 dotenv 实现变量引用和嵌套展开。它允许在 .env 文件中使用 ${VAR} 语法引用其他变量。

// .env
BASE_URL=https://api.example.com
USERS_ENDPOINT=${BASE_URL}/users

// app.js
const dotenv = require('dotenv');
const dotenvExpand = require('dotenv-expand');
const myEnv = dotenv.config();
dotenvExpand(myEnv);

console.log(process.env.USERS_ENDPOINT); // 'https://api.example.com/users'

dotenv-safe:带校验的安全加载器

dotenv-safedotenv 基础上增加了必需变量校验。它要求提供一个 .env.example 文件作为模板,确保所有必需变量都已定义,否则抛出错误。

// .env.example(模板)
DB_HOST=
API_KEY=

// .env(实际值)
DB_HOST=localhost
API_KEY=12345

// app.js
require('dotenv-safe').config();
// 如果 .env 缺少 DB_HOST 或 API_KEY,程序会立即报错退出

config:面向多环境的结构化配置系统

config 提供完整的配置管理解决方案。它从 config/ 目录加载 JSON/YAML/JS 格式的配置文件,支持开发、测试、生产等多环境覆盖,并可通过 NODE_ENV 自动切换。

// config/default.json
{
  "db": {
    "host": "localhost",
    "port": 5432
  },
  "api": {
    "timeout": 5000
  }
}

// config/production.json
{
  "db": {
    "host": "prod-db.internal"
  }
}

// app.js
const config = require('config');
console.log(config.get('db.host')); // 开发环境: 'localhost';生产环境: 'prod-db.internal'

config 不依赖 process.env,而是维护自己的配置对象,可通过 custom-environment-variables.json 将环境变量映射到配置树中。

🔐 安全性与可靠性考量

缺失变量处理

  • dotenv:静默忽略缺失变量,可能导致运行时 undefined 错误。
  • dotenv-safe:启动时强制校验,避免因配置缺失导致服务异常。
  • config:调用 config.get('missing.key') 会抛出明确错误,便于早期发现问题。
  • dotenv-expand:若引用的变量未定义,默认展开为空字符串(如 ${UNSET}''),可能引发意外行为。

敏感信息保护

  • 所有方案都要求 .env 文件加入 .gitignore,防止密钥泄露。
  • config 支持通过 custom-environment-variables.json 将敏感值从环境变量注入,避免硬编码在配置文件中:
// config/custom-environment-variables.json
{
  "db": {
    "password": "DB_PASSWORD"
  }
}

此时 config.get('db.password') 实际读取 process.env.DB_PASSWORD

🧩 复杂度与扩展能力

方案配置结构多环境支持动态计算类型安全
dotenv扁平键值
dotenv-expand扁平键值 + 插值✅(有限)
dotenv-safe扁平键值 + 校验
config嵌套对象✅(通过 JS 文件)✅(配合 TypeScript)
  • config 允许使用 .js 配置文件执行逻辑:
// config/development.js
module.exports = {
  db: {
    url: process.env.DATABASE_URL || 'postgres://localhost/dev'
  },
  features: {
    beta: true
  }
};
  • dotenv 生态(包括 dotenv-expand/dotenv-safe)始终局限于字符串键值,无法表达嵌套结构或布尔/数字类型(需手动转换)。

🛠️ 典型工程场景推荐

场景 1:简单静态网站或小型工具

  • 需求:只需几个环境变量(如 VITE_API_BASE),无多环境差异。
  • 推荐dotenv + 手动校验
  • 理由:零配置开销,符合 KISS 原则。

场景 2:需要变量复用的中型应用

  • 需求:API 端点基于基础 URL 拼接(如 ${API_BASE}/v1/users)。
  • 推荐dotenv + dotenv-expand
  • 理由:避免重复定义,提升 .env 可维护性。

场景 3:CI/CD 流水线中的关键服务

  • 需求:必须确保所有必需变量在部署前已设置,防止因配置缺失导致服务中断。
  • 推荐dotenv-safe
  • 理由:启动时校验提供强保障,契合 DevOps 最佳实践。

场景 4:企业级全栈应用

  • 需求:多环境(dev/staging/prod)、嵌套配置、动态逻辑、与 TypeScript 集成。
  • 推荐config
  • 理由:结构化配置降低认知负荷,环境隔离避免“在我机器上能跑”问题。

⚠️ 常见陷阱与最佳实践

陷阱 1:混淆 process.env 与配置对象

  • dotenv 系列直接污染全局 process.env,可能导致意外副作用。
  • config 提供隔离的配置命名空间,更安全。

陷阱 2:过度依赖 .env 文件

  • 在容器化环境(如 Docker/K8s)中,环境变量应通过部署平台注入,而非挂载 .env 文件。
  • configcustom-environment-variables.json 更适合此类场景。

最佳实践:分层配置策略

  1. 默认值:在代码或 config/default.json 中提供安全默认值。
  2. 环境覆盖:通过 NODE_ENV 加载特定环境配置。
  3. 运行时注入:敏感值通过环境变量传入(configcustom-environment-variables.jsondotenv-safe 的校验)。
  4. 启动校验:使用 dotenv-safeconfig.util.loadFileConfigs() 验证必需字段。

📊 总结:如何选择?

方案适用场景关键优势主要局限
dotenv超小型项目、快速原型极简、零学习成本无校验、无结构、无多环境支持
dotenv-expand需要变量插值的 .env减少重复、提升可读性仍为扁平结构,错误处理弱
dotenv-safe需要强校验的脚本/服务启动时保障配置完整性仅限字符串键值,无嵌套支持
config中大型应用、多环境部署结构化、环境隔离、类型友好配置目录约定,学习曲线稍陡

💡 终极建议

  • 不要混用:避免同时使用 dotenvconfig,除非明确知道如何协调(例如用 dotenv 加载基础变量,再由 config 通过 custom-environment-variables.json 引用)。
  • 前端项目注意:Vite/Rollup/Webpack 等构建工具通常内置环境变量处理(如 Vite 的 import.meta.env),此时 dotenv 仅用于构建时,运行时变量需通过构建工具暴露。
  • 安全第一:无论选择哪种方案,永远不要提交 .env 文件到版本控制,并在 CI 中使用 dotenv-safe 或等效校验步骤。

选择配置方案的本质,是在 简单性可控性 之间做权衡。理解每个工具的设计边界,才能在复杂度增长时从容演进架构。

如何选择: dotenv vs config vs dotenv-safe vs dotenv-expand

  • dotenv:

    选择 dotenv 如果你只需要从 .env 文件加载简单的键值对到 process.env,项目规模小或处于原型阶段。它是最轻量、最通用的起点,适合不需要校验、插值或多环境支持的场景。但需自行处理缺失变量和类型转换问题。

  • config:

    选择 config 如果你需要管理复杂的多环境配置(如开发、测试、生产),希望使用嵌套的 JSON/YAML/JS 配置文件,并需要通过 NODE_ENV 自动切换环境。它适合中大型项目,尤其是那些需要结构化配置、动态计算逻辑以及与 TypeScript 集成的场景。但要注意它引入了额外的目录约定和学习成本。

  • dotenv-safe:

    选择 dotenv-safe 如果你依赖 .env 文件,但要求在应用启动时强制校验所有必需变量是否已定义(通过 .env.example 模板)。它非常适合 CI/CD 流水线或关键服务,能防止因配置缺失导致的运行时错误。但它仍然局限于扁平的字符串键值,无法处理复杂配置结构。

  • dotenv-expand:

    选择 dotenv-expand 如果你已经在使用 dotenv,并且需要在 .env 文件中通过 ${VAR} 语法引用其他变量(例如拼接 API 端点)。它必须与 dotenv 配合使用,适合需要减少重复配置但又不想引入完整配置系统的项目。注意它不提供校验或嵌套结构支持。

dotenv的README

dotenv NPM version downloads

dotenv

Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env. Storing configuration in the environment separate from code is based on The Twelve-Factor App methodology.

Watch the tutorial

 

Usage

Install it.

npm install dotenv --save

Create a .env file in the root of your project:

# .env
S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"

And as early as possible in your application, import and configure dotenv:

require('dotenv').config() // or import 'dotenv/config' if you're using ES6
...
console.log(process.env) // remove this after you've confirmed it is working

That's it. process.env now has the keys and values you defined in your .env file:

 

Advanced

ES6

Import with ES6:

import 'dotenv/config'

ES6 import if you need to set config options:

import dotenv from 'dotenv'
dotenv.config({ path: '/custom/path/to/.env' })
bun
bun add dotenv
yarn
yarn add dotenv
pnpm
pnpm add dotenv
Monorepos

For monorepos with a structure like apps/backend/app.js, put it the .env file in the root of the folder where your app.js process runs.

# app/backend/.env
S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"
Multiline Values

If you need multiline variables, for example private keys, those are now supported (>= v15.0.0) with line breaks:

PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
...
Kh9NV...
...
-----END RSA PRIVATE KEY-----"

Alternatively, you can double quote strings and use the \n character:

PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END RSA PRIVATE KEY-----\n"
Comments

Comments may be added to your file on their own line or inline:

# This is a comment
SECRET_KEY=YOURSECRETKEYGOESHERE # comment
SECRET_HASH="something-with-a-#-hash"

Comments begin where a # exists, so if your value contains a # please wrap it in quotes. This is a breaking change from >= v15.0.0 and on.

Parsing

The engine which parses the contents of your file containing environment variables is available to use. It accepts a String or Buffer and will return an Object with the parsed keys and values.

const dotenv = require('dotenv')
const buf = Buffer.from('BASIC=basic')
const config = dotenv.parse(buf) // will return an object
console.log(typeof config, config) // object { BASIC : 'basic' }
Preload

Note: Consider using dotenvx instead of preloading. I am now doing (and recommending) so.

It serves the same purpose (you do not need to require and load dotenv), adds better debugging, and works with ANY language, framework, or platform. – motdotla

You can use the --require (-r) command line option to preload dotenv. By doing this, you do not need to require and load dotenv in your application code.

$ node -r dotenv/config your_script.js

The configuration options below are supported as command line arguments in the format dotenv_config_<option>=value

$ node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env dotenv_config_debug=true

Additionally, you can use environment variables to set configuration options. Command line arguments will precede these.

$ DOTENV_CONFIG_<OPTION>=value node -r dotenv/config your_script.js
$ DOTENV_CONFIG_ENCODING=latin1 DOTENV_CONFIG_DEBUG=true node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env
Variable Expansion

Use dotenvx for variable expansion.

Reference and expand variables already on your machine for use in your .env file.

# .env
USERNAME="username"
DATABASE_URL="postgres://${USERNAME}@localhost/my_database"
// index.js
console.log('DATABASE_URL', process.env.DATABASE_URL)
$ dotenvx run --debug -- node index.js
[dotenvx@0.14.1] injecting env (2) from .env
DATABASE_URL postgres://username@localhost/my_database
Command Substitution

Use dotenvx for command substitution.

Add the output of a command to one of your variables in your .env file.

# .env
DATABASE_URL="postgres://$(whoami)@localhost/my_database"
// index.js
console.log('DATABASE_URL', process.env.DATABASE_URL)
$ dotenvx run --debug -- node index.js
[dotenvx@0.14.1] injecting env (1) from .env
DATABASE_URL postgres://yourusername@localhost/my_database
Encryption

Use dotenvx for encryption.

Add encryption to your .env files with a single command.

$ dotenvx set HELLO Production -f .env.production
$ echo "console.log('Hello ' + process.env.HELLO)" > index.js

$ DOTENV_PRIVATE_KEY_PRODUCTION="<.env.production private key>" dotenvx run -- node index.js
[dotenvx] injecting env (2) from .env.production
Hello Production

learn more

Multiple Environments

Use dotenvx to manage multiple environments.

Run any environment locally. Create a .env.ENVIRONMENT file and use -f to load it. It's straightforward, yet flexible.

$ echo "HELLO=production" > .env.production
$ echo "console.log('Hello ' + process.env.HELLO)" > index.js

$ dotenvx run -f=.env.production -- node index.js
Hello production
> ^^

or with multiple .env files

$ echo "HELLO=local" > .env.local
$ echo "HELLO=World" > .env
$ echo "console.log('Hello ' + process.env.HELLO)" > index.js

$ dotenvx run -f=.env.local -f=.env -- node index.js
Hello local

more environment examples

Production

Use dotenvx for production deploys.

Create a .env.production file.

$ echo "HELLO=production" > .env.production

Encrypt it.

$ dotenvx encrypt -f .env.production

Set DOTENV_PRIVATE_KEY_PRODUCTION (found in .env.keys) on your server.

$ heroku config:set DOTENV_PRIVATE_KEY_PRODUCTION=value

Commit your .env.production file to code and deploy.

$ git add .env.production
$ git commit -m "encrypted .env.production"
$ git push heroku main

Dotenvx will decrypt and inject the secrets at runtime using dotenvx run -- node index.js.

Syncing

Use dotenvx to sync your .env files.

Encrypt them with dotenvx encrypt -f .env and safely include them in source control. Your secrets are securely synced with your git.

This still subscribes to the twelve-factor app rules by generating a decryption key separate from code.

More Examples

See examples of using dotenv with various frameworks, languages, and configurations.

 

Agents

dotenvx-as2

Software is changing, and dotenv must change with it—that is why I built agentic secret storage (AS2). Agents run code without humans at terminals, so plaintext .env files are the wrong primitive.

AS2 is built for autonomous software: encrypted by default, zero console access, and cryptography‑first delivery that keeps operators out of the loop.

It is backed by Vestauth, the trusted, pioneering auth layer for agents—giving each agent a cryptographic identity so requests are signed with private keys and verified with public keys. No shared secrets to leak.

It's what I'm using now. - motdotla

Quickstart

Install vestauth and initialize your agent.

npm i -g vestauth

vestauth agent init

Your agent sets secrets with a simple curl endpoint:

vestauth agent curl -X POST https://as2.dotenvx.com/set -d '{"KEY":"value"}'

And your agent gets secrets with a simple curl endpoint:

vestauth agent curl https://as2.dotenvx.com/get?key=KEY

That's it! This new primitive unlocks secrets access for agents without human-in-the-loop, oauth flows, or API keys. It's the future for agents.

 

FAQ

Should I commit my `.env` file?

No.

Unless you encrypt it with dotenvx. Then we recommend you do.

What about variable expansion?

Use dotenvx.

Should I have multiple `.env` files?

We recommend creating one .env file per environment. Use .env for local/development, .env.production for production and so on. This still follows the twelve factor principles as each is attributed individually to its own environment. Avoid custom set ups that work in inheritance somehow (.env.production inherits values form .env for example). It is better to duplicate values if necessary across each .env.environment file.

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

Additionally, we recommend using dotenvx to encrypt and manage these.

How do I use dotenv with `import`?

Simply..

// index.mjs (ESM)
import 'dotenv/config' // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import
import express from 'express'

A little background..

When you run a module containing an import declaration, the modules it imports are loaded first, then each module body is executed in a depth-first traversal of the dependency graph, avoiding cycles by skipping anything already executed.

ES6 In Depth: Modules

What does this mean in plain language? It means you would think the following would work but it won't.

errorReporter.mjs:

class Client {
  constructor (apiKey) {
    console.log('apiKey', apiKey)

    this.apiKey = apiKey
  }
}

export default new Client(process.env.API_KEY)

index.mjs:

// Note: this is INCORRECT and will not work
import * as dotenv from 'dotenv'
dotenv.config()

import errorReporter from './errorReporter.mjs' // process.env.API_KEY will be blank!

process.env.API_KEY will be blank.

Instead, index.mjs should be written as..

import 'dotenv/config'

import errorReporter from './errorReporter.mjs'

Does that make sense? It's a bit unintuitive, but it is how importing of ES6 modules work. Here is a working example of this pitfall.

There are two alternatives to this approach:

  1. Preload with dotenvx: dotenvx run -- node index.js (Note: you do not need to import dotenv with this approach)
  2. Create a separate file that will execute config first as outlined in this comment on #133
Can I customize/write plugins for dotenv?

Yes! dotenv.config() returns an object representing the parsed .env file. This gives you everything you need to continue setting values on process.env. For example:

const dotenv = require('dotenv')
const variableExpansion = require('dotenv-expand')
const myEnv = dotenv.config()
variableExpansion(myEnv)
What rules does the parsing engine follow?

The parsing engine currently supports the following rules:

  • BASIC=basic becomes {BASIC: 'basic'}
  • empty lines are skipped
  • lines beginning with # are treated as comments
  • # marks the beginning of a comment (unless when the value is wrapped in quotes)
  • empty values become empty strings (EMPTY= becomes {EMPTY: ''})
  • inner quotes are maintained (think JSON) (JSON={"foo": "bar"} becomes {JSON:"{\"foo\": \"bar\"}")
  • whitespace is removed from both ends of unquoted values (see more on trim) (FOO= some value becomes {FOO: 'some value'})
  • single and double quoted values are escaped (SINGLE_QUOTE='quoted' becomes {SINGLE_QUOTE: "quoted"})
  • single and double quoted values maintain whitespace from both ends (FOO=" some value " becomes {FOO: ' some value '})
  • double quoted values expand new lines (MULTILINE="new\nline" becomes
{MULTILINE: 'new
line'}
  • backticks are supported (BACKTICK_KEY=`This has 'single' and "double" quotes inside of it.`)
What about syncing and securing .env files?

Use dotenvx to unlock syncing encrypted .env files over git.

What if I accidentally commit my `.env` file to code?

Remove it, remove git history and then install the git pre-commit hook to prevent this from ever happening again.

npm i -g @dotenvx/dotenvx
dotenvx precommit --install
What happens to environment variables that were already set?

By default, we 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.

If instead, you want to override process.env use the override option.

require('dotenv').config({ override: true })
How can I prevent committing my `.env` file to a Docker build?

Use the docker prebuild hook.

# Dockerfile
...
RUN curl -fsS https://dotenvx.sh/ | sh
...
RUN dotenvx prebuild
CMD ["dotenvx", "run", "--", "node", "index.js"]
How come my environment variables are not showing up for React?

Your React code is run in Webpack, where the fs module or even the process global itself are not accessible out-of-the-box. process.env can only be injected through Webpack configuration.

If you are using react-scripts, which is distributed through create-react-app, it has dotenv built in but with a quirk. Preface your environment variables with REACT_APP_. See this stack overflow for more details.

If you are using other frameworks (e.g. Next.js, Gatsby...), you need to consult their documentation for how to inject environment variables into the client.

Why is the `.env` file not loading my environment variables successfully?

Most likely your .env file is not in the correct place. See this stack overflow.

Turn on debug mode and try again..

require('dotenv').config({ debug: true })

You will receive a helpful error outputted to your console.

Why am I getting the error `Module not found: Error: Can't resolve 'crypto|os|path'`?

You are using dotenv on the front-end and have not included a polyfill. Webpack < 5 used to include these for you. Do the following:

npm install node-polyfill-webpack-plugin

Configure your webpack.config.js to something like the following.

require('dotenv').config()

const path = require('path');
const webpack = require('webpack')

const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')

module.exports = {
  mode: 'development',
  entry: './src/index.ts',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  plugins: [
    new NodePolyfillPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        HELLO: JSON.stringify(process.env.HELLO)
      }
    }),
  ]
};

Alternatively, just use dotenv-webpack which does this and more behind the scenes for you.

 

Docs

Dotenv exposes four functions:

  • config
  • parse
  • populate

Config

config will read your .env file, parse the contents, assign it to process.env, and return an Object with a parsed key containing the loaded content or an error key if it failed.

const result = dotenv.config()

if (result.error) {
  throw result.error
}

console.log(result.parsed)

You can additionally, pass options to config.

Options

path

Default: path.resolve(process.cwd(), '.env')

Specify a custom path if your file containing environment variables is located elsewhere.

require('dotenv').config({ path: '/custom/path/to/.env' })

By default, config will look for a file called .env in the current working directory.

Pass in multiple files as an array, and they will be parsed in order and combined with process.env (or option.processEnv, if set). The first value set for a variable will win, unless the options.override flag is set, in which case the last value set will win. If a value already exists in process.env and the options.override flag is NOT set, no changes will be made to that value.

require('dotenv').config({ path: ['.env.local', '.env'] })
quiet

Default: false

Suppress runtime logging message.

// index.js
require('dotenv').config({ quiet: false }) // change to true to suppress
console.log(`Hello ${process.env.HELLO}`)
# .env
HELLO=World
$ node index.js
[dotenv@17.0.0] injecting env (1) from .env
Hello World
encoding

Default: utf8

Specify the encoding of your file containing environment variables.

require('dotenv').config({ encoding: 'latin1' })
debug

Default: false

Turn on logging to help debug why certain keys or values are not being set as you expect.

require('dotenv').config({ debug: process.env.DEBUG })
override

Default: false

Override any environment variables that have already been set on your machine with values from your .env file(s). If multiple files have been provided in option.path the override will also be used as each file is combined with the next. Without override being set, the first value wins. With override set the last value wins.

require('dotenv').config({ override: true })
processEnv

Default: process.env

Specify an object to write your environment variables to. Defaults to process.env environment variables.

const myObject = {}
require('dotenv').config({ processEnv: myObject })

console.log(myObject) // values from .env
console.log(process.env) // this was not changed or written to

Parse

The engine which parses the contents of your file containing environment variables is available to use. It accepts a String or Buffer and will return an Object with the parsed keys and values.

const dotenv = require('dotenv')
const buf = Buffer.from('BASIC=basic')
const config = dotenv.parse(buf) // will return an object
console.log(typeof config, config) // object { BASIC : 'basic' }

Options

debug

Default: false

Turn on logging to help debug why certain keys or values are not being set as you expect.

const dotenv = require('dotenv')
const buf = Buffer.from('hello world')
const opt = { debug: true }
const config = dotenv.parse(buf, opt)
// expect a debug message because the buffer is not in KEY=VAL form

Populate

The engine which populates the contents of your .env file to process.env is available for use. It accepts a target, a source, and options. This is useful for power users who want to supply their own objects.

For example, customizing the source:

const dotenv = require('dotenv')
const parsed = { HELLO: 'world' }

dotenv.populate(process.env, parsed)

console.log(process.env.HELLO) // world

For example, customizing the source AND target:

const dotenv = require('dotenv')
const parsed = { HELLO: 'universe' }
const target = { HELLO: 'world' } // empty object

dotenv.populate(target, parsed, { override: true, debug: true })

console.log(target) // { HELLO: 'universe' }

options

Debug

Default: false

Turn on logging to help debug why certain keys or values are not being populated as you expect.

override

Default: false

Override any environment variables that have already been set.

 

CHANGELOG

See CHANGELOG.md

 

Who's using dotenv?

These npm modules depend on it.

Projects that expand it often use the keyword "dotenv" on npm.