From 09ce1298b1665a6ce3d79cfc2464617d25ede68d Mon Sep 17 00:00:00 2001 From: Andy Edwards Date: Tue, 7 Oct 2025 15:53:49 -0500 Subject: [PATCH 01/65] fix: make DotenvPopulateInput equivalent to NodeJS.ProcessEnv type fix #767 --- lib/main.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main.d.ts b/lib/main.d.ts index 0bbb9cc6..3e57f24f 100644 --- a/lib/main.d.ts +++ b/lib/main.d.ts @@ -124,7 +124,7 @@ export interface DotenvPopulateOptions { } export interface DotenvPopulateInput { - [name: string]: string; + [name: string]: string | undefined; } /** From 520e1b99193f2ae8003cddbc821a23dd771b8ae7 Mon Sep 17 00:00:00 2001 From: Andy Edwards Date: Tue, 7 Oct 2025 15:55:08 -0500 Subject: [PATCH 02/65] test: add test for NodeJS.ProcessEnv type input --- tests/types/test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/types/test.ts b/tests/types/test.ts index 6df4676a..3b8ad3c2 100644 --- a/tests/types/test.ts +++ b/tests/types/test.ts @@ -17,3 +17,8 @@ const dbHost: string = parsed["DB_HOST"]; const parsedFromBuffer = parse(Buffer.from("JUSTICE=league\n")); const justice: string = parsedFromBuffer["JUSTICE"]; + +config({ + // make sure the type accepts process.env (it didn't in the past) + processEnv: process.env, +}); From 974d6425f999a5a51268a23ef7d3389890daf870 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 5 Feb 2026 12:08:01 -0800 Subject: [PATCH 03/65] remove sponsor --- README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/README.md b/README.md index c942898f..94b37536 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,6 @@
-**Special thanks to [our sponsors](https://github.com/sponsors/motdotla)** - - -
- Tuple -
- Tuple, the premier screen sharing app for developers on macOS and Windows. -
-
# dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) From d4e20eef41825151aeb01f1ea9d85d889f28cbf5 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 5 Feb 2026 12:10:07 -0800 Subject: [PATCH 04/65] announcing vestauth --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 94b37536..8c655e96 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,9 @@
-🎉 announcing dotenvx. run anywhere, multi-environment, encrypted envs. +🎉 announcing vestauth. auth for agents–from the creator of dotenv and dotenvx.
  -
- -
- # dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) dotenv From 671adebcfafdfa08a5ec7f2596f648006e12d195 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 5 Feb 2026 12:11:39 -0800 Subject: [PATCH 05/65] announcing vestauth --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c655e96..480e6c81 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
-🎉 announcing vestauth. auth for agents–from the creator of dotenv and dotenvx. +🎉 announcing vestauth. auth for agents–from the creator of dotenv and dotenvx.
  From 95329df0be35a99b47f932debe62562acf89bcb0 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 5 Feb 2026 12:12:23 -0800 Subject: [PATCH 06/65] announcing vestauth --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 480e6c81..a68a8d65 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
-🎉 announcing vestauth. auth for agents–from the creator of dotenv and dotenvx. +🎉 announcing vestauth: auth for agents–from the creator of dotenv and dotenvx.
  From 2145ed6847247855b32e839c27fe52967fb5fa18 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 5 Feb 2026 12:13:05 -0800 Subject: [PATCH 07/65] announcing vestauth --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a68a8d65..e7c6d43d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
-🎉 announcing vestauth: auth for agents–from the creator of dotenv and dotenvx. +🎉 announcing vestauth: auth for agents–from the creator of dotenv and dotenvx.
  From 79ef59cd0e93e4eb2153595270af56da9cd1d958 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 5 Feb 2026 12:14:23 -0800 Subject: [PATCH 08/65] fix video display --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index e7c6d43d..5c736b2f 100644 --- a/README.md +++ b/README.md @@ -44,10 +44,8 @@ pnpm add dotenv ## 🏗️ Usage -
how to use dotenv video tutorial youtube/@dotenvorg -
Create a `.env` file in the root of your project (if using a monorepo structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs): From ebcc9ff0916995fd84fb79d81a5eab9c6232494b Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 5 Feb 2026 12:15:42 -0800 Subject: [PATCH 09/65] update README --- README-es.md | 15 +-------------- README.md | 2 +- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/README-es.md b/README-es.md index 978a73b5..06214611 100644 --- a/README-es.md +++ b/README-es.md @@ -1,22 +1,9 @@
-🎉 announcing dotenvx. run anywhere, multi-environment, encrypted envs. +🎉 new announcement vestauth: auth for agents–from the creator of dotenv and dotenvx.
  -
- -**Special thanks to [our sponsors](https://github.com/sponsors/motdotla)** - - -
- Tuple -
- Tuple, the premier screen sharing app for developers on macOS and Windows. -
-
-
- # dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) dotenv diff --git a/README.md b/README.md index 5c736b2f..967c26ed 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
-🎉 announcing vestauth: auth for agents–from the creator of dotenv and dotenvx. +🎉 new announcement vestauth: auth for agents–from the creator of dotenv and dotenvx.
  From 408868e7b1d2919b6d511bd426b7e02061b54ccd Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 5 Feb 2026 12:33:08 -0800 Subject: [PATCH 10/65] =?UTF-8?q?changelog=20=F0=9F=AA=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90e19a0a..06ff71d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,14 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. -## [Unreleased](https://github.com/motdotla/dotenv/compare/v17.2.3...master) +## [Unreleased](https://github.com/motdotla/dotenv/compare/v17.2.4...master) + +## [17.2.4](https://github.com/motdotla/dotenv/compare/v17.2.3...v17.2.4) (2026-02-05) + +### Changed + +* Make `DotenvPopulateInput` accept `NodeJS.ProcessEnv` type ([#915](https://github.com/motdotla/dotenv/pull/915)) +- Give back to dotenv by checking out my newest project [vestauth](https://github.com/vestauth/vestauth). It is auth for agents. Thank you for using my software. ## [17.2.3](https://github.com/motdotla/dotenv/compare/v17.2.2...v17.2.3) (2025-09-29) From fabbdf24c59d0cac3b5acd45daf9fcb2b40dd98d Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 5 Feb 2026 12:39:31 -0800 Subject: [PATCH 11/65] 17.2.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 08468710..a8fdab9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dotenv", - "version": "17.2.3", + "version": "17.2.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "dotenv", - "version": "17.2.3", + "version": "17.2.4", "license": "BSD-2-Clause", "devDependencies": { "@types/node": "^18.11.3", diff --git a/package.json b/package.json index ec347e39..9e2f33bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dotenv", - "version": "17.2.3", + "version": "17.2.4", "description": "Loads environment variables from .env file", "main": "lib/main.js", "types": "lib/main.d.ts", From 73c886cf72b8dc8e88cbd1f805fc655fc332d7cf Mon Sep 17 00:00:00 2001 From: Rosano <1680612+rosano@users.noreply.github.com> Date: Tue, 10 Feb 2026 10:27:55 +0100 Subject: [PATCH 12/65] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 967c26ed..dfdf9573 100644 --- a/README.md +++ b/README.md @@ -335,7 +335,7 @@ console.log(`Hello ${process.env.HELLO}`) ```ini # .env -.env +HELLO=World ``` ```sh From 8c5ea4dc27329246e72edf4d81c89d84ec9ebb1a Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Wed, 11 Feb 2026 15:17:24 -0800 Subject: [PATCH 13/65] add initial as2 messages --- lib/main.js | 2 ++ tests/test-config.js | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/lib/main.js b/lib/main.js index 67712ca5..75de50d8 100644 --- a/lib/main.js +++ b/lib/main.js @@ -17,6 +17,8 @@ const TIPS = [ '✅ audit secrets and track compliance: https://dotenvx.com/ops', '🔄 add secrets lifecycle management: https://dotenvx.com/ops', '🔑 add access controls to secrets: https://dotenvx.com/ops', + '🤖 agentic secret storage with Dotenvx AS2: https://dotenvx.com/as2', + '⚡️ runtime secrets for agents: https://dotenvx.com/as2', '🛠️ run anywhere with `dotenvx run -- yourcommand`', '⚙️ specify custom .env file path with { path: \'/custom/path/.env\' }', '⚙️ enable debug logging with { debug: true }', diff --git a/tests/test-config.js b/tests/test-config.js index f4bb0928..75650c8f 100644 --- a/tests/test-config.js +++ b/tests/test-config.js @@ -338,6 +338,8 @@ t.test('displays random tips from the tips array', ct => { '✅ audit secrets and track compliance: https://dotenvx.com/ops', '🔄 add secrets lifecycle management: https://dotenvx.com/ops', '🔑 add access controls to secrets: https://dotenvx.com/ops', + '🤖 agentic secret storage with Dotenvx AS2: https://dotenvx.com/as2', + '⚡️ runtime secrets for agents: https://dotenvx.com/as2', '🛠️ run anywhere with `dotenvx run -- yourcommand`', '⚙️ specify custom .env file path with { path: \'/custom/path/.env\' }', '⚙️ enable debug logging with { debug: true }', @@ -402,6 +404,8 @@ t.test('displays random tips from the tips array with fallback for isTTY false', '✅ audit secrets and track compliance: https://dotenvx.com/ops', '🔄 add secrets lifecycle management: https://dotenvx.com/ops', '🔑 add access controls to secrets: https://dotenvx.com/ops', + '🤖 agentic secret storage with Dotenvx AS2: https://dotenvx.com/as2', + '⚡️ runtime secrets for agents: https://dotenvx.com/as2', '🛠️ run anywhere with `dotenvx run -- yourcommand`', '⚙️ specify custom .env file path with { path: \'/custom/path/.env\' }', '⚙️ enable debug logging with { debug: true }', From 990fe8290d08c9a8b38695d20a29b7d18882e039 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Wed, 11 Feb 2026 15:20:42 -0800 Subject: [PATCH 14/65] update messages --- lib/main.js | 11 +++-------- tests/test-config.js | 22 ++++++---------------- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/lib/main.js b/lib/main.js index 75de50d8..967107c9 100644 --- a/lib/main.js +++ b/lib/main.js @@ -11,14 +11,9 @@ const TIPS = [ '🔐 encrypt with Dotenvx: https://dotenvx.com', '🔐 prevent committing .env to code: https://dotenvx.com/precommit', '🔐 prevent building .env in docker: https://dotenvx.com/prebuild', - '📡 add observability to secrets: https://dotenvx.com/ops', - '👥 sync secrets across teammates & machines: https://dotenvx.com/ops', - '🗂️ backup and recover secrets: https://dotenvx.com/ops', - '✅ audit secrets and track compliance: https://dotenvx.com/ops', - '🔄 add secrets lifecycle management: https://dotenvx.com/ops', - '🔑 add access controls to secrets: https://dotenvx.com/ops', - '🤖 agentic secret storage with Dotenvx AS2: https://dotenvx.com/as2', - '⚡️ runtime secrets for agents: https://dotenvx.com/as2', + '🤖 agentic secret storage: https://dotenvx.com/as2', + '⚡️ secrets for agents: https://dotenvx.com/as2', + '🛡️ auth for agents: https://vestauth.com', '🛠️ run anywhere with `dotenvx run -- yourcommand`', '⚙️ specify custom .env file path with { path: \'/custom/path/.env\' }', '⚙️ enable debug logging with { debug: true }', diff --git a/tests/test-config.js b/tests/test-config.js index 75650c8f..3213962f 100644 --- a/tests/test-config.js +++ b/tests/test-config.js @@ -332,14 +332,9 @@ t.test('displays random tips from the tips array', ct => { '🔐 encrypt with Dotenvx: https://dotenvx.com', '🔐 prevent committing .env to code: https://dotenvx.com/precommit', '🔐 prevent building .env in docker: https://dotenvx.com/prebuild', - '📡 add observability to secrets: https://dotenvx.com/ops', - '👥 sync secrets across teammates & machines: https://dotenvx.com/ops', - '🗂️ backup and recover secrets: https://dotenvx.com/ops', - '✅ audit secrets and track compliance: https://dotenvx.com/ops', - '🔄 add secrets lifecycle management: https://dotenvx.com/ops', - '🔑 add access controls to secrets: https://dotenvx.com/ops', - '🤖 agentic secret storage with Dotenvx AS2: https://dotenvx.com/as2', - '⚡️ runtime secrets for agents: https://dotenvx.com/as2', + '🤖 agentic secret storage: https://dotenvx.com/as2', + '⚡️ secrets for agents: https://dotenvx.com/as2', + '🛡️ auth for agents: https://vestauth.com', '🛠️ run anywhere with `dotenvx run -- yourcommand`', '⚙️ specify custom .env file path with { path: \'/custom/path/.env\' }', '⚙️ enable debug logging with { debug: true }', @@ -398,14 +393,9 @@ t.test('displays random tips from the tips array with fallback for isTTY false', '🔐 encrypt with Dotenvx: https://dotenvx.com', '🔐 prevent committing .env to code: https://dotenvx.com/precommit', '🔐 prevent building .env in docker: https://dotenvx.com/prebuild', - '📡 add observability to secrets: https://dotenvx.com/ops', - '👥 sync secrets across teammates & machines: https://dotenvx.com/ops', - '🗂️ backup and recover secrets: https://dotenvx.com/ops', - '✅ audit secrets and track compliance: https://dotenvx.com/ops', - '🔄 add secrets lifecycle management: https://dotenvx.com/ops', - '🔑 add access controls to secrets: https://dotenvx.com/ops', - '🤖 agentic secret storage with Dotenvx AS2: https://dotenvx.com/as2', - '⚡️ runtime secrets for agents: https://dotenvx.com/as2', + '🤖 agentic secret storage: https://dotenvx.com/as2', + '⚡️ secrets for agents: https://dotenvx.com/as2', + '🛡️ auth for agents: https://vestauth.com', '🛠️ run anywhere with `dotenvx run -- yourcommand`', '⚙️ specify custom .env file path with { path: \'/custom/path/.env\' }', '⚙️ enable debug logging with { debug: true }', From c959f71b89f0080e48176dcbb85c6a90fccb7c63 Mon Sep 17 00:00:00 2001 From: iMaverick007 Date: Thu, 12 Feb 2026 18:21:51 +0530 Subject: [PATCH 15/65] Add explicit test for duplicate keys in parse (last value wins) --- tests/test-parse.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test-parse.js b/tests/test-parse.js index a5583015..58df19bb 100644 --- a/tests/test-parse.js +++ b/tests/test-parse.js @@ -82,6 +82,9 @@ t.equal(parsed.SPACED_KEY, 'parsed', 'parses keys and values surrounded by space const payload = dotenv.parse(Buffer.from('BUFFER=true')) t.equal(payload.BUFFER, 'true', 'should parse a buffer into an object') +const duplicate = dotenv.parse(Buffer.from('DUP=one\nDUP=two')) +t.equal(duplicate.DUP, 'two', 'last duplicate key wins') + const expectedPayload = { SERVER: 'localhost', PASSWORD: 'password', DB: 'tests' } const RPayload = dotenv.parse(Buffer.from('SERVER=localhost\rPASSWORD=password\rDB=tests\r')) From f62ba1ee363d31eed36898eac3c9ffc9f667c7f3 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:07:41 -0800 Subject: [PATCH 16/65] Add AS2 agents section to README --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index dfdf9573..30976b35 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Dotenv is a zero-dependency module that loads environment variables from a `.env * [🏗️ Usage (.env)](#%EF%B8%8F-usage) * [🌴 Multiple Environments 🆕](#-manage-multiple-environments) * [🚀 Deploying (encryption) 🆕](#-deploying) +* [🤖 Agents (AS2) 🆕](#-agents-as2) * [📚 Examples](#-examples) * [📖 Docs](#-documentation) * [❓ FAQ](#-faq) @@ -254,6 +255,33 @@ Hello Production [learn more](https://github.com/dotenvx/dotenvx?tab=readme-ov-file#encryption) +## 🤖 Agents (AS2) + +AS2 is agentic secret storage from Dotenvx. + +> Secrets designed for agents. No logins. No consoles. Pure cryptography. + +### Quickstart + +Install vestauth and initialize your agent. (AS2 uses vestauth to authenticate agents.) + +```bash +npm i -g vestauth +vestauth agent init +``` + +Your agent can `set` secrets: + +```bash +vestauth agent curl -X POST https://as2.dotenvx.com/set '{"KEY":"value"}' +``` + +Your agent can `get` secrets: + +```bash +vestauth agent curl https://as2.dotenvx.com/get?key=KEY +``` + ## 📚 Examples See [examples](https://github.com/dotenv-org/examples) of using dotenv with various frameworks, languages, and configurations. From d06baea5132526077d29ecf2e931bf5c24dd7612 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:12:03 -0800 Subject: [PATCH 17/65] update README --- README.md | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 30976b35..27e595e4 100644 --- a/README.md +++ b/README.md @@ -14,17 +14,13 @@ Dotenv is a zero-dependency module that loads environment variables from a `.env [![LICENSE](https://img.shields.io/github/license/motdotla/dotenv.svg)](LICENSE) [![codecov](https://codecov.io/gh/motdotla/dotenv-expand/graph/badge.svg?token=pawWEyaMfg)](https://codecov.io/gh/motdotla/dotenv-expand) -* [🌱 Install](#-install) -* [🏗️ Usage (.env)](#%EF%B8%8F-usage) -* [🌴 Multiple Environments 🆕](#-manage-multiple-environments) -* [🚀 Deploying (encryption) 🆕](#-deploying) -* [🤖 Agents (AS2) 🆕](#-agents-as2) -* [📚 Examples](#-examples) -* [📖 Docs](#-documentation) -* [❓ FAQ](#-faq) -* [⏱️ Changelog](./CHANGELOG.md) - -## 🌱 Install +* [Install](#install) +* [Usage](#usage) +* [Multiple Environments](#multiple-environments) +* [Deploying](#deploying) +* [Agents (AS2) 🆕](#agents-as2) + +## Install ```bash npm install dotenv --save @@ -34,15 +30,11 @@ You can also use an npm-compatible package manager like yarn, bun or pnpm: ```bash yarn add dotenv -``` -```bash bun add dotenv -``` -```bash pnpm add dotenv ``` -## 🏗️ Usage +## Usage how to use dotenv video tutorial @@ -210,7 +202,7 @@ Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate `.env.ci`, `.env.p You need to deploy your secrets in a cloud-agnostic manner? Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate a private decryption key that is set on your production server. -## 🌴 Manage Multiple Environments +## Multiple Environments Use [dotenvx](https://github.com/dotenvx/dotenvx) @@ -238,7 +230,7 @@ Hello local [more environment examples](https://dotenvx.com/docs/quickstart/environments) -## 🚀 Deploying +## Deploying Use [dotenvx](https://github.com/dotenvx/dotenvx). @@ -255,7 +247,7 @@ Hello Production [learn more](https://github.com/dotenvx/dotenvx?tab=readme-ov-file#encryption) -## 🤖 Agents (AS2) +## Agents (AS2) AS2 is agentic secret storage from Dotenvx. From 2cf362aa947a174793ece4f3fecb7634a203ec17 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:14:42 -0800 Subject: [PATCH 18/65] update README --- README.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 27e595e4..499f29ee 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,8 @@ bun add dotenv pnpm add dotenv ``` +  + ## Usage @@ -202,6 +204,8 @@ Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate `.env.ci`, `.env.p You need to deploy your secrets in a cloud-agnostic manner? Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate a private decryption key that is set on your production server. +  + ## Multiple Environments Use [dotenvx](https://github.com/dotenvx/dotenvx) @@ -230,6 +234,8 @@ Hello local [more environment examples](https://dotenvx.com/docs/quickstart/environments) +  + ## Deploying Use [dotenvx](https://github.com/dotenvx/dotenvx). @@ -247,6 +253,8 @@ Hello Production [learn more](https://github.com/dotenvx/dotenvx?tab=readme-ov-file#encryption) +  + ## Agents (AS2) AS2 is agentic secret storage from Dotenvx. @@ -295,7 +303,7 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari * [nestjs](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nestjs) * [fastify](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-fastify) -## 📖 Documentation +## Documentation Dotenv exposes four functions: @@ -478,7 +486,9 @@ Default: `false` Override any environment variables that have already been set. -## ❓ FAQ +  + +## FAQ ### Why is the `.env` file not loading my environment variables successfully? @@ -686,10 +696,14 @@ CMD ["dotenvx", "run", "--", "node", "index.js"] See [CONTRIBUTING.md](CONTRIBUTING.md) +  + ## CHANGELOG See [CHANGELOG.md](CHANGELOG.md) +  + ## Who's using dotenv? [These npm modules depend on it.](https://www.npmjs.com/browse/depended/dotenv) From 2ae52b82a03a2ee729bffe5b26d2034d74180272 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:25:20 -0800 Subject: [PATCH 19/65] update README --- README.md | 60 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 499f29ee..9d9d33ae 100644 --- a/README.md +++ b/README.md @@ -4,25 +4,19 @@   -# dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) +# dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) [![LICENSE](https://img.shields.io/github/license/motdotla/dotenv.svg)](LICENSE) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard) [![codecov](https://codecov.io/gh/motdotla/dotenv-expand/graph/badge.svg?token=pawWEyaMfg)](https://codecov.io/gh/motdotla/dotenv-expand) dotenv Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. -[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard) -[![LICENSE](https://img.shields.io/github/license/motdotla/dotenv.svg)](LICENSE) -[![codecov](https://codecov.io/gh/motdotla/dotenv-expand/graph/badge.svg?token=pawWEyaMfg)](https://codecov.io/gh/motdotla/dotenv-expand) +  -* [Install](#install) -* [Usage](#usage) -* [Multiple Environments](#multiple-environments) -* [Deploying](#deploying) -* [Agents (AS2) 🆕](#agents-as2) +### Quickstart -## Install +Install and use it in code just like `dotenv`. -```bash +```sh npm install dotenv --save ``` @@ -34,8 +28,52 @@ bun add dotenv pnpm add dotenv ``` +Create a `.env` file in the root of your project (if using a monorepo structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs): + +```dosini +S3_BUCKET="YOURS3BUCKET" +SECRET_KEY="YOURSECRETKEYGOESHERE" +``` + +As early as possible in your application, import and configure dotenv: + +```javascript +require('dotenv').config() +console.log(process.env) // remove this after you've confirmed it is working +``` + +.. [or using ES6?](#how-do-i-use-dotenv-with-import) + +```javascript +import 'dotenv/config' +``` + +ES6 import if you need to set config options: + +```javascript +import dotenv from 'dotenv' + +dotenv.config({ path: '/custom/path/to/.env' }) +``` + +That's it. `process.env` now has the keys and values you defined in your `.env` file: + +```javascript +require('dotenv').config() +// or import 'dotenv/config' if you're using ES6 + +... + +s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) +``` +   +* [Usage](#usage) +* [Multiple Environments](#multiple-environments) +* [Deploying](#deploying) +* [Agents (AS2) 🆕](#agents-as2) + ## Usage From ea6148975ae734edae6afb30d56d17053d768286 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:25:49 -0800 Subject: [PATCH 20/65] update README --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 9d9d33ae..0ad0f2da 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,3 @@ - - -  - # dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) [![LICENSE](https://img.shields.io/github/license/motdotla/dotenv.svg)](LICENSE) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard) [![codecov](https://codecov.io/gh/motdotla/dotenv-expand/graph/badge.svg?token=pawWEyaMfg)](https://codecov.io/gh/motdotla/dotenv-expand) dotenv From c7dfd7516b4122fd7a8e028214ca6396d15244bc Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:26:42 -0800 Subject: [PATCH 21/65] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ad0f2da..793aa57a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) [![LICENSE](https://img.shields.io/github/license/motdotla/dotenv.svg)](LICENSE) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard) [![codecov](https://codecov.io/gh/motdotla/dotenv-expand/graph/badge.svg?token=pawWEyaMfg)](https://codecov.io/gh/motdotla/dotenv-expand) +# dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) [![LICENSE](https://img.shields.io/github/license/motdotla/dotenv.svg)](LICENSE) [![codecov](https://codecov.io/gh/motdotla/dotenv-expand/graph/badge.svg?token=pawWEyaMfg)](https://codecov.io/gh/motdotla/dotenv-expand) dotenv From 20775904c4a4fda7c831bc4f702b7f4038a21444 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:30:47 -0800 Subject: [PATCH 22/65] update README --- README.md | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 793aa57a..7e48540c 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,46 @@ -# dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) [![LICENSE](https://img.shields.io/github/license/motdotla/dotenv.svg)](LICENSE) [![codecov](https://codecov.io/gh/motdotla/dotenv-expand/graph/badge.svg?token=pawWEyaMfg)](https://codecov.io/gh/motdotla/dotenv-expand) - dotenv -Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. +# dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) [![downloads](https://img.shields.io/npm/dw/dotenv)](https://www.npmjs.com/package/dotenv) + +> Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology.   ### Quickstart -Install and use it in code just like `dotenv`. +Install it. ```sh npm install dotenv --save ``` -You can also use an npm-compatible package manager like yarn, bun or pnpm: +
with yarn, bun, or pnpm (expand)
-```bash +```sh yarn add dotenv bun add dotenv pnpm add dotenv ``` -Create a `.env` file in the root of your project (if using a monorepo structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs): +  + +
+ +Create a `.env` file in the root of your project: ```dosini S3_BUCKET="YOURS3BUCKET" SECRET_KEY="YOURSECRETKEYGOESHERE" ``` +
for monorepos (expand)
+ +If using a monorepo structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs. + +  + +
+ As early as possible in your application, import and configure dotenv: ```javascript From 04ba055bd4288b3cfcd40d2d85efc903795377fb Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:36:00 -0800 Subject: [PATCH 23/65] update README --- README.md | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7e48540c..389bc563 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,9 @@ Install it. npm install dotenv --save ``` -
with yarn, bun, or pnpm (expand)
+
learn more
+ +You can use any npm-compatible package manager like yarn, bun, or pnpm. ```sh yarn add dotenv @@ -26,16 +28,25 @@ pnpm add dotenv
+  + Create a `.env` file in the root of your project: -```dosini +```ini +# .env S3_BUCKET="YOURS3BUCKET" SECRET_KEY="YOURSECRETKEYGOESHERE" ``` -
for monorepos (expand)
+
learn more
+ +For monorepos with a structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs. -If using a monorepo structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs. +```ini +# app/backend/.env +S3_BUCKET="YOURS3BUCKET" +SECRET_KEY="YOURSECRETKEYGOESHERE" +```   @@ -48,13 +59,15 @@ require('dotenv').config() console.log(process.env) // remove this after you've confirmed it is working ``` -.. [or using ES6?](#how-do-i-use-dotenv-with-import) +
learn more
+ +If you are [using ES6](#how-do-i-use-dotenv-with-import): ```javascript import 'dotenv/config' ``` -ES6 import if you need to set config options: +or using ES6 import with config options: ```javascript import dotenv from 'dotenv' @@ -62,14 +75,13 @@ import dotenv from 'dotenv' dotenv.config({ path: '/custom/path/to/.env' }) ``` +
+ That's it. `process.env` now has the keys and values you defined in your `.env` file: ```javascript -require('dotenv').config() -// or import 'dotenv/config' if you're using ES6 - +require('dotenv').config() // or import 'dotenv/config' if you're using ES6 ... - s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) ``` @@ -89,7 +101,7 @@ s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) Create a `.env` file in the root of your project (if using a monorepo structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs): -```dosini +```ini S3_BUCKET="YOURS3BUCKET" SECRET_KEY="YOURSECRETKEYGOESHERE" ``` @@ -130,7 +142,7 @@ s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) If you need multiline variables, for example private keys, those are now supported (`>= v15.0.0`) with line breaks: -```dosini +```ini PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY----- ... Kh9NV... @@ -140,7 +152,7 @@ Kh9NV... Alternatively, you can double quote strings and use the `\n` character: -```dosini +```ini PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END RSA PRIVATE KEY-----\n" ``` @@ -148,7 +160,7 @@ PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END RSA PRIVATE KEY Comments may be added to your file on their own line or inline: -```dosini +```ini # This is a comment SECRET_KEY=YOURSECRETKEYGOESHERE # comment SECRET_HASH="something-with-a-#-hash" From 24f848e5e03bb075f8ff14e2a2e401d064e383cf Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:37:06 -0800 Subject: [PATCH 24/65] update README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 389bc563..64877dee 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ SECRET_KEY="YOURSECRETKEYGOESHERE"
-As early as possible in your application, import and configure dotenv: +And as early as possible in your application, import and configure dotenv: ```javascript require('dotenv').config() @@ -77,6 +77,8 @@ dotenv.config({ path: '/custom/path/to/.env' })
+  + That's it. `process.env` now has the keys and values you defined in your `.env` file: ```javascript From ea1d6699af7becd235d9bed5dbd9779663325f44 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:41:08 -0800 Subject: [PATCH 25/65] update README --- README.md | 67 ++++++++++++++++++------------------------------------- 1 file changed, 22 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 64877dee..8ca41038 100644 --- a/README.md +++ b/README.md @@ -14,22 +14,6 @@ Install it. npm install dotenv --save ``` -
learn more
- -You can use any npm-compatible package manager like yarn, bun, or pnpm. - -```sh -yarn add dotenv -bun add dotenv -pnpm add dotenv -``` - -  - -
- -  - Create a `.env` file in the root of your project: ```ini @@ -38,55 +22,48 @@ S3_BUCKET="YOURS3BUCKET" SECRET_KEY="YOURSECRETKEYGOESHERE" ``` -
learn more
- -For monorepos with a structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs. - -```ini -# app/backend/.env -S3_BUCKET="YOURS3BUCKET" -SECRET_KEY="YOURSECRETKEYGOESHERE" -``` - -  - -
- And as early as possible in your application, import and configure dotenv: ```javascript -require('dotenv').config() +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 ``` -
learn more
- -If you are [using ES6](#how-do-i-use-dotenv-with-import): +That's it. `process.env` now has the keys and values you defined in your `.env` file: ```javascript -import 'dotenv/config' +require('dotenv').config() +... +s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) ``` -or using ES6 import with config options: +
more details (expand)
-```javascript -import dotenv from 'dotenv' +Install with any npm-compatible package manager. -dotenv.config({ path: '/custom/path/to/.env' }) +```sh +yarn add dotenv +bun add dotenv +pnpm add dotenv ``` -
+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. -  +```ini +# app/backend/.env +S3_BUCKET="YOURS3BUCKET" +SECRET_KEY="YOURSECRETKEYGOESHERE" +``` -That's it. `process.env` now has the keys and values you defined in your `.env` file: +And if you are [using ES6](#how-do-i-use-dotenv-with-import) import with config options: ```javascript -require('dotenv').config() // or import 'dotenv/config' if you're using ES6 -... -s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) +import dotenv from 'dotenv' +dotenv.config({ path: '/custom/path/to/.env' }) ``` +
+   * [Usage](#usage) From 4224dad78f7d34d7ffd8182ab8868250daba3a03 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:41:30 -0800 Subject: [PATCH 26/65] update README --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 8ca41038..80594449 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ > Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. -  - ### Quickstart Install it. From 7601f8ec5708f1888a98c73634db652bc0f3f481 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:41:51 -0800 Subject: [PATCH 27/65] update README --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 80594449..a0ea39dc 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ > Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. -### Quickstart - Install it. ```sh From 90c7e55a84bd4db38064c5f9f91f06f6b6446325 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:44:51 -0800 Subject: [PATCH 28/65] update README --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a0ea39dc..42c9d37b 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,7 @@ 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: -```javascript -require('dotenv').config() -... -s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) -``` - -
more details (expand)
+
learn more
Install with any npm-compatible package manager. @@ -55,7 +49,13 @@ And if you are [using ES6](#how-do-i-use-dotenv-with-import) import with config ```javascript import dotenv from 'dotenv' -dotenv.config({ path: '/custom/path/to/.env' }) +dotenv.config({ path: 'app/backend/.env' }) +``` + +That's it. Make use of `process.env.S3_BUCKET`. + +```javascript +s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) ```
From 725d52a5a777bcd632ca638daec07fb5733970d5 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:45:47 -0800 Subject: [PATCH 29/65] update README --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 42c9d37b..47dd8556 100644 --- a/README.md +++ b/README.md @@ -50,11 +50,9 @@ And if you are [using ES6](#how-do-i-use-dotenv-with-import) import with config ```javascript import dotenv from 'dotenv' dotenv.config({ path: 'app/backend/.env' }) -``` -That's it. Make use of `process.env.S3_BUCKET`. +... -```javascript s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) ``` From 364a415ba49d2a40b80f34948032a1bb5ea6d1bd Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:46:12 -0800 Subject: [PATCH 30/65] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 47dd8556..48ed4fb8 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ > Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. +### Quickstart + Install it. ```sh From 263a9372aed4432d5add45dda4bf975da56ec2c4 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:49:06 -0800 Subject: [PATCH 31/65] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 48ed4fb8..1bf06f4e 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ # dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) [![downloads](https://img.shields.io/npm/dw/dotenv)](https://www.npmjs.com/package/dotenv) > Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. +> +> [2 minute tutorial 📺](https://www.youtube.com/watch?v=YtkZR0NFd1g) ### Quickstart From 3e00c83e48acf03f426b953501c97fcdade5b9cb Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:49:44 -0800 Subject: [PATCH 32/65] update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1bf06f4e..174f5ed6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -dotenv - # dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) [![downloads](https://img.shields.io/npm/dw/dotenv)](https://www.npmjs.com/package/dotenv) +dotenv + > Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. > > [2 minute tutorial 📺](https://www.youtube.com/watch?v=YtkZR0NFd1g) From 630fd7585872df51a1483fb9cab260f21b4e79fb Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 10:55:40 -0800 Subject: [PATCH 33/65] update README --- README.md | 120 +++++++++++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 174f5ed6..9ac62c39 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,9 @@ > > [2 minute tutorial 📺](https://www.youtube.com/watch?v=YtkZR0NFd1g) -### Quickstart +  + +### Usage Install it. @@ -69,53 +71,9 @@ s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) * [Deploying](#deploying) * [Agents (AS2) 🆕](#agents-as2) -## Usage - - -how to use dotenv video tutorial -youtube/@dotenvorg - - -Create a `.env` file in the root of your project (if using a monorepo structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs): - -```ini -S3_BUCKET="YOURS3BUCKET" -SECRET_KEY="YOURSECRETKEYGOESHERE" -``` - -As early as possible in your application, import and configure dotenv: - -```javascript -require('dotenv').config() -console.log(process.env) // remove this after you've confirmed it is working -``` - -.. [or using ES6?](#how-do-i-use-dotenv-with-import) - -```javascript -import 'dotenv/config' -``` - -ES6 import if you need to set config options: - -```javascript -import dotenv from 'dotenv' - -dotenv.config({ path: '/custom/path/to/.env' }) -``` - -That's it. `process.env` now has the keys and values you defined in your `.env` file: - -```javascript -require('dotenv').config() -// or import 'dotenv/config' if you're using ES6 - -... - -s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) -``` +## Advanced -### Multiline values +
Multiline Values
If you need multiline variables, for example private keys, those are now supported (`>= v15.0.0`) with line breaks: @@ -133,7 +91,8 @@ 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
Comments may be added to your file on their own line or inline: @@ -145,7 +104,10 @@ 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 +
+ + +
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. @@ -156,7 +118,8 @@ const config = dotenv.parse(buf) // will return an object console.log(typeof config, config) // object { BASIC : 'basic' } ``` -### Preload +
+
Preload
> Note: Consider using [`dotenvx`](https://github.com/dotenvx/dotenvx) instead of preloading. I am now doing (and recommending) so. > @@ -184,7 +147,8 @@ $ DOTENV_CONFIG_
+
Variable Expansion
Use [dotenvx](https://github.com/dotenvx/dotenvx) to use variable expansion. @@ -205,7 +169,8 @@ $ dotenvx run --debug -- node index.js DATABASE_URL postgres://username@localhost/my_database ``` -### Command Substitution +
+
Command Substitution
Use [dotenvx](https://github.com/dotenvx/dotenvx) to use command substitution. @@ -225,18 +190,63 @@ $ dotenvx run --debug -- node index.js DATABASE_URL postgres://yourusername@localhost/my_database ``` -### Syncing +
+
Syncing
You need to keep `.env` files in sync between machines, environments, or team members? Use [dotenvx](https://github.com/dotenvx/dotenvx) to encrypt your `.env` files and safely include them in source control. This still subscribes to the twelve-factor app rules by generating a decryption key separate from code. -### Multiple Environments +
+
Multiple Environments
Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate `.env.ci`, `.env.production` files, and more. -### Deploying +
+ +
Deploying
You need to deploy your secrets in a cloud-agnostic manner? Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate a private decryption key that is set on your production server. +
+ +Create a `.env` file in the root of your project (if using a monorepo structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs): + +```ini +S3_BUCKET="YOURS3BUCKET" +SECRET_KEY="YOURSECRETKEYGOESHERE" +``` + +As early as possible in your application, import and configure dotenv: + +```javascript +require('dotenv').config() +console.log(process.env) // remove this after you've confirmed it is working +``` + +.. [or using ES6?](#how-do-i-use-dotenv-with-import) + +```javascript +import 'dotenv/config' +``` + +ES6 import if you need to set config options: + +```javascript +import dotenv from 'dotenv' + +dotenv.config({ path: '/custom/path/to/.env' }) +``` + +That's it. `process.env` now has the keys and values you defined in your `.env` file: + +```javascript +require('dotenv').config() +// or import 'dotenv/config' if you're using ES6 + +... + +s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) +``` +   ## Multiple Environments From 170c345cd7708896a885b17c144387b0a462f70e Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:01:27 -0800 Subject: [PATCH 34/65] update README --- README.md | 66 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 9ac62c39..94fdf3a6 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,11 @@ > > [2 minute tutorial 📺](https://www.youtube.com/watch?v=YtkZR0NFd1g) +* [usage](#usage) +* [environments](#multiple-environments) +* [deploying](#deploying) +* [agents 🆕](#agents-as2) +   ### Usage @@ -28,51 +33,66 @@ And as early as possible in your application, import and configure dotenv: ```javascript 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: -
learn more
-Install with any npm-compatible package manager. +  -```sh -yarn add dotenv -bun add dotenv -pnpm add dotenv -``` +## Advanced -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. +
ES6
-```ini -# app/backend/.env -S3_BUCKET="YOURS3BUCKET" -SECRET_KEY="YOURSECRETKEYGOESHERE" +Import with [ES6](#how-do-i-use-dotenv-with-import): + +```javascript +import 'dotenv/config' ``` -And if you are [using ES6](#how-do-i-use-dotenv-with-import) import with config options: +ES6 import if you need to set config options: ```javascript import dotenv from 'dotenv' -dotenv.config({ path: 'app/backend/.env' }) +dotenv.config({ path: '/custom/path/to/.env' }) +``` -... +
+
bun
-s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) +```sh +bun add dotenv ```
+
yarn
-  +```sh +yarn add dotenv +``` + +
+
pnpm
-* [Usage](#usage) -* [Multiple Environments](#multiple-environments) -* [Deploying](#deploying) -* [Agents (AS2) 🆕](#agents-as2) +```sh +pnpm add dotenv +``` -## Advanced +
+
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. + +```ini +# 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: @@ -105,8 +125,6 @@ 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. From 69ff042676ed1b7e7a5b9cbe18e16108992f3e81 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:03:13 -0800 Subject: [PATCH 35/65] update README --- README.md | 50 +++----------------------------------------------- 1 file changed, 3 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 94fdf3a6..db5bd954 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,13 @@ dotenv -> Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. -> -> [2 minute tutorial 📺](https://www.youtube.com/watch?v=YtkZR0NFd1g) +Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. -* [usage](#usage) -* [environments](#multiple-environments) -* [deploying](#deploying) -* [agents 🆕](#agents-as2) +[Watch the tutorial](https://www.youtube.com/watch?v=YtkZR0NFd1g)   -### Usage +## Usage Install it. @@ -226,45 +221,6 @@ You need to deploy your secrets in a cloud-agnostic manner? Use [dotenvx](https:
-Create a `.env` file in the root of your project (if using a monorepo structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs): - -```ini -S3_BUCKET="YOURS3BUCKET" -SECRET_KEY="YOURSECRETKEYGOESHERE" -``` - -As early as possible in your application, import and configure dotenv: - -```javascript -require('dotenv').config() -console.log(process.env) // remove this after you've confirmed it is working -``` - -.. [or using ES6?](#how-do-i-use-dotenv-with-import) - -```javascript -import 'dotenv/config' -``` - -ES6 import if you need to set config options: - -```javascript -import dotenv from 'dotenv' - -dotenv.config({ path: '/custom/path/to/.env' }) -``` - -That's it. `process.env` now has the keys and values you defined in your `.env` file: - -```javascript -require('dotenv').config() -// or import 'dotenv/config' if you're using ES6 - -... - -s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) -``` -   ## Multiple Environments From 1c31958561868a7d2d1932b5d89f8ef724bf2d42 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:03:52 -0800 Subject: [PATCH 36/65] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index db5bd954..e8ad08a2 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. +  + [Watch the tutorial](https://www.youtube.com/watch?v=YtkZR0NFd1g)   From f3f065c2e314653c6a8e1e98e699b63490be7a9f Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:04:09 -0800 Subject: [PATCH 37/65] update README --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index e8ad08a2..ec16d691 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,6 @@ Dotenv is a zero-dependency module that loads environment variables from a `.env [Watch the tutorial](https://www.youtube.com/watch?v=YtkZR0NFd1g) -  - ## Usage Install it. From b4c632cf2cc0f5f4677c42e14eff541b24612b2d Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:06:31 -0800 Subject: [PATCH 38/65] update README --- README.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ec16d691..4d76f430 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,10 @@ Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. -  - [Watch the tutorial](https://www.youtube.com/watch?v=YtkZR0NFd1g) +  + ## Usage Install it. @@ -54,6 +54,8 @@ import dotenv from 'dotenv' dotenv.config({ path: '/custom/path/to/.env' }) ``` +  +
bun
@@ -61,6 +63,8 @@ dotenv.config({ path: '/custom/path/to/.env' }) bun add dotenv ``` +  +
yarn
@@ -68,6 +72,8 @@ bun add dotenv yarn add dotenv ``` +  +
pnpm
@@ -75,6 +81,8 @@ yarn add dotenv pnpm add dotenv ``` +  +
Monorepos
@@ -87,6 +95,8 @@ S3_BUCKET="YOURS3BUCKET" SECRET_KEY="YOURSECRETKEYGOESHERE" ``` +  +
Multiline Values
@@ -106,6 +116,8 @@ 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
@@ -119,6 +131,8 @@ 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
@@ -131,6 +145,8 @@ const config = dotenv.parse(buf) // will return an object console.log(typeof config, config) // object { BASIC : 'basic' } ``` +  +
Preload
@@ -160,6 +176,8 @@ $ DOTENV_CONFIG_
Variable Expansion
@@ -182,6 +200,8 @@ $ dotenvx run --debug -- node index.js DATABASE_URL postgres://username@localhost/my_database ``` +  +
Command Substitution
@@ -203,22 +223,30 @@ $ dotenvx run --debug -- node index.js DATABASE_URL postgres://yourusername@localhost/my_database ``` +  +
Syncing
You need to keep `.env` files in sync between machines, environments, or team members? Use [dotenvx](https://github.com/dotenvx/dotenvx) to encrypt your `.env` files and safely include them in source control. This still subscribes to the twelve-factor app rules by generating a decryption key separate from code. +  +
Multiple Environments
Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate `.env.ci`, `.env.production` files, and more. +  +
Deploying
You need to deploy your secrets in a cloud-agnostic manner? Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate a private decryption key that is set on your production server. +  +
  From 996dca4d7e6b80d56ee4717af87fa7fe06b8a8f7 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:07:25 -0800 Subject: [PATCH 39/65] update README --- README.md | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 4d76f430..8224e0d3 100644 --- a/README.md +++ b/README.md @@ -235,24 +235,6 @@ You need to keep `.env` files in sync between machines, environments, or team me
Multiple Environments
-Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate `.env.ci`, `.env.production` files, and more. - -  - -
- -
Deploying
- -You need to deploy your secrets in a cloud-agnostic manner? Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate a private decryption key that is set on your production server. - -  - -
- -  - -## Multiple Environments - Use [dotenvx](https://github.com/dotenvx/dotenvx) Run any environment locally. Create a `.env.ENVIRONMENT` file and use `--env-file` to load it. It's straightforward, yet flexible. @@ -281,6 +263,17 @@ Hello local   +
+
Deploying
+ +You need to deploy your secrets in a cloud-agnostic manner? Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate a private decryption key that is set on your production server. + +  + +
+ +  + ## Deploying Use [dotenvx](https://github.com/dotenvx/dotenvx). From 48ad9e8b65b3df33e7f409374b780614426a8de7 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:13:07 -0800 Subject: [PATCH 40/65] update README --- README.md | 62 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 8224e0d3..df3a4d7e 100644 --- a/README.md +++ b/README.md @@ -226,9 +226,23 @@ DATABASE_URL postgres://yourusername@localhost/my_database   -
Syncing
-You need to keep `.env` files in sync between machines, environments, or team members? Use [dotenvx](https://github.com/dotenvx/dotenvx) to encrypt your `.env` files and safely include them in source control. This still subscribes to the twelve-factor app rules by generating a decryption key separate from code. +
Encryption
+ +Use [dotenvx](https://github.com/dotenvx/dotenvx). + +Add encryption to your `.env` files with a single command. Pass the `--encrypt` flag. + +``` +$ dotenvx set HELLO Production --encrypt -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](https://github.com/dotenvx/dotenvx?tab=readme-ov-file#encryption)   @@ -264,32 +278,46 @@ Hello local  
-
Deploying
- -You need to deploy your secrets in a cloud-agnostic manner? Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate a private decryption key that is set on your production server. +
Production
-  +Use [dotenvx](https://github.com/dotenvx/dotenvx) -
+Create a `.env.production` file. -  +```sh +$ echo "HELLO=production" > .env.production +``` -## Deploying +Encrypt it. -Use [dotenvx](https://github.com/dotenvx/dotenvx). +```sh +$ dotenvx encrypt -f .env.production +``` -Add encryption to your `.env` files with a single command. Pass the `--encrypt` flag. +Set `DOTENV_PRIVATE_KEY_PRODUCTION` (found in `.env.keys`) on your server. ``` -$ dotenvx set HELLO Production --encrypt -f .env.production -$ echo "console.log('Hello ' + process.env.HELLO)" > index.js +$ heroku config:set DOTENV_PRIVATE_KEY_PRODUCTION=value +``` + +Commit your `.env.production` file to code and deploy. -$ DOTENV_PRIVATE_KEY_PRODUCTION="<.env.production private key>" dotenvx run -- node index.js -[dotenvx] injecting env (2) from .env.production -Hello Production +``` +$ git add .env.production +$ git commit -m "encrypted .env.production" +$ git push heroku main ``` -[learn more](https://github.com/dotenvx/dotenvx?tab=readme-ov-file#encryption) +  + +
+
Syncing
+ +You need to keep `.env` files in sync between machines, environments, or team members? Use [dotenvx](https://github.com/dotenvx/dotenvx) to encrypt your `.env` files and safely include them in source control. This still subscribes to the twelve-factor app rules by generating a decryption key separate from code. + +  + +
  From 983faea2f290cc20a1803e5da25bce563316994b Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:18:41 -0800 Subject: [PATCH 41/65] update README --- README.md | 73 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index df3a4d7e..0bf2fb0e 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ $ DOTENV_CONFIG_ENCODING=latin1 DOTENV_CONFIG_DEBUG=true node -r dotenv/config y
Variable Expansion
-Use [dotenvx](https://github.com/dotenvx/dotenvx) to use variable expansion. +Use [dotenvx](https://github.com/dotenvx/dotenvx) for variable expansion. Reference and expand variables already on your machine for use in your .env file. @@ -205,7 +205,7 @@ DATABASE_URL postgres://username@localhost/my_database
Command Substitution
-Use [dotenvx](https://github.com/dotenvx/dotenvx) to use command substitution. +Use [dotenvx](https://github.com/dotenvx/dotenvx) for command substitution. Add the output of a command to one of your variables in your .env file. @@ -229,12 +229,12 @@ DATABASE_URL postgres://yourusername@localhost/my_database
Encryption
-Use [dotenvx](https://github.com/dotenvx/dotenvx). +Use [dotenvx](https://github.com/dotenvx/dotenvx) for encryption. -Add encryption to your `.env` files with a single command. Pass the `--encrypt` flag. +Add encryption to your `.env` files with a single command. ``` -$ dotenvx set HELLO Production --encrypt -f .env.production +$ 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 @@ -249,15 +249,15 @@ Hello Production
Multiple Environments
-Use [dotenvx](https://github.com/dotenvx/dotenvx) +Use [dotenvx](https://github.com/dotenvx/dotenvx) to manage multiple environments. -Run any environment locally. Create a `.env.ENVIRONMENT` file and use `--env-file` to load it. It's straightforward, yet flexible. +Run any environment locally. Create a `.env.ENVIRONMENT` file and use `-f` to load it. It's straightforward, yet flexible. ```bash $ echo "HELLO=production" > .env.production $ echo "console.log('Hello ' + process.env.HELLO)" > index.js -$ dotenvx run --env-file=.env.production -- node index.js +$ dotenvx run -f=.env.production -- node index.js Hello production > ^^ ``` @@ -269,7 +269,7 @@ $ echo "HELLO=local" > .env.local $ echo "HELLO=World" > .env $ echo "console.log('Hello ' + process.env.HELLO)" > index.js -$ dotenvx run --env-file=.env.local --env-file=.env -- node index.js +$ dotenvx run -f=.env.local -f=.env -- node index.js Hello local ``` @@ -280,7 +280,7 @@ Hello local
Production
-Use [dotenvx](https://github.com/dotenvx/dotenvx) +Use [dotenvx](https://github.com/dotenvx/dotenvx) for production deploys. Create a `.env.production` file. @@ -308,12 +308,42 @@ $ 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
-You need to keep `.env` files in sync between machines, environments, or team members? Use [dotenvx](https://github.com/dotenvx/dotenvx) to encrypt your `.env` files and safely include them in source control. This still subscribes to the twelve-factor app rules by generating a decryption key separate from code. +Use [dotenvx](https://github.com/dotenvx/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](https://github.com/dotenv-org/examples) of using dotenv with various frameworks, languages, and configurations. + +* [nodejs](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nodejs) +* [nodejs (debug on)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nodejs-debug) +* [nodejs (override on)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nodejs-override) +* [nodejs (processEnv override)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-custom-target) +* [esm](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-esm) +* [esm (preload)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-esm-preload) +* [typescript](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-typescript) +* [typescript parse](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-typescript-parse) +* [typescript config](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-typescript-config) +* [webpack](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-webpack) +* [webpack (plugin)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-webpack2) +* [react](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-react) +* [react (typescript)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-react-typescript) +* [express](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-express) +* [nestjs](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nestjs) +* [fastify](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-fastify)   @@ -348,26 +378,7 @@ Your agent can `get` secrets: vestauth agent curl https://as2.dotenvx.com/get?key=KEY ``` -## 📚 Examples - -See [examples](https://github.com/dotenv-org/examples) of using dotenv with various frameworks, languages, and configurations. - -* [nodejs](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nodejs) -* [nodejs (debug on)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nodejs-debug) -* [nodejs (override on)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nodejs-override) -* [nodejs (processEnv override)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-custom-target) -* [esm](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-esm) -* [esm (preload)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-esm-preload) -* [typescript](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-typescript) -* [typescript parse](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-typescript-parse) -* [typescript config](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-typescript-config) -* [webpack](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-webpack) -* [webpack (plugin)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-webpack2) -* [react](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-react) -* [react (typescript)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-react-typescript) -* [express](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-express) -* [nestjs](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nestjs) -* [fastify](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-fastify) +  ## Documentation From 8b8493f9d38edd7846f2006bd7fa767de712f5ba Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:21:33 -0800 Subject: [PATCH 42/65] update README --- README.md | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/README.md b/README.md index 0bf2fb0e..b1ef3e0e 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,6 @@ import dotenv from 'dotenv' dotenv.config({ path: '/custom/path/to/.env' }) ``` -  -
bun
@@ -63,8 +61,6 @@ dotenv.config({ path: '/custom/path/to/.env' }) bun add dotenv ``` -  -
yarn
@@ -72,8 +68,6 @@ bun add dotenv yarn add dotenv ``` -  -
pnpm
@@ -81,10 +75,7 @@ yarn add dotenv 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. @@ -95,8 +86,6 @@ S3_BUCKET="YOURS3BUCKET" SECRET_KEY="YOURSECRETKEYGOESHERE" ``` -  -
Multiline Values
@@ -116,8 +105,6 @@ 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
@@ -131,8 +118,6 @@ 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
@@ -145,8 +130,6 @@ const config = dotenv.parse(buf) // will return an object console.log(typeof config, config) // object { BASIC : 'basic' } ``` -  -
Preload
@@ -176,8 +159,6 @@ $ DOTENV_CONFIG_
Variable Expansion
@@ -200,8 +181,6 @@ $ dotenvx run --debug -- node index.js DATABASE_URL postgres://username@localhost/my_database ``` -  -
Command Substitution
@@ -223,10 +202,7 @@ $ dotenvx run --debug -- node index.js DATABASE_URL postgres://yourusername@localhost/my_database ``` -  -
-
Encryption
Use [dotenvx](https://github.com/dotenvx/dotenvx) for encryption. @@ -244,8 +220,6 @@ Hello Production [learn more](https://github.com/dotenvx/dotenvx?tab=readme-ov-file#encryption) -  -
Multiple Environments
@@ -275,8 +249,6 @@ Hello local [more environment examples](https://dotenvx.com/docs/quickstart/environments) -  -
Production
@@ -310,8 +282,6 @@ $ git push heroku main Dotenvx will decrypt and inject the secrets at runtime using `dotenvx run -- node index.js`. -  -
Syncing
@@ -321,8 +291,6 @@ Encrypt them with `dotenvx encrypt -f .env` and safely include them in source co This still subscribes to the twelve-factor app rules by generating a decryption key separate from code. -  -
More Examples
@@ -345,13 +313,11 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari * [nestjs](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nestjs) * [fastify](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-fastify) -  -
  -## Agents (AS2) +## Agents AS2 is agentic secret storage from Dotenvx. From 26f3023a0658203cfdba326669459b666353af65 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:31:31 -0800 Subject: [PATCH 43/65] Wrap FAQ in details --- README.md | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index b1ef3e0e..51da1852 100644 --- a/README.md +++ b/README.md @@ -533,7 +533,8 @@ Override any environment variables that have already been set. ## FAQ -### Why is the `.env` file not loading my environment variables successfully? +
+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](https://stackoverflow.com/questions/42335016/dotenv-file-is-not-loading-environment-variables). @@ -544,23 +545,29 @@ require('dotenv').config({ debug: true }) ``` You will receive a helpful error outputted to your console. +
-### Should I commit my `.env` file? +
+Should I commit my `.env` file? 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. +
-### Should I have multiple `.env` files? +
+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](http://12factor.net/config) +
-### What rules does the parsing engine follow? +
+What rules does the parsing engine follow? The parsing engine currently supports the following rules: @@ -581,8 +588,10 @@ line'} ``` - backticks are supported (`` BACKTICK_KEY=`This has 'single' and "double" quotes inside of it.` ``) +
-### What happens to environment variables that were already set? +
+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. @@ -591,16 +600,20 @@ If instead, you want to override `process.env` use the `override` option. ```javascript require('dotenv').config({ override: true }) ``` +
-### How come my environment variables are not showing up for React? +
+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`](https://www.npmjs.com/package/react-scripts), which is distributed through [`create-react-app`](https://create-react-app.dev/), it has dotenv built in but with a quirk. Preface your environment variables with `REACT_APP_`. See [this stack overflow](https://stackoverflow.com/questions/42182577/is-it-possible-to-use-dotenv-in-a-react-project) 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. +
-### Can I customize/write plugins for dotenv? +
+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: @@ -610,8 +623,10 @@ const variableExpansion = require('dotenv-expand') const myEnv = dotenv.config() variableExpansion(myEnv) ``` +
-### How do I use dotenv with `import`? +
+How do I use dotenv with `import`? Simply.. @@ -666,8 +681,10 @@ 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](https://github.com/motdotla/dotenv/issues/133#issuecomment-255298822) +
-### Why am I getting the error `Module not found: Error: Can't resolve 'crypto|os|path'`? +
+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: @@ -704,16 +721,22 @@ module.exports = { ``` Alternatively, just use [dotenv-webpack](https://github.com/mrsteele/dotenv-webpack) which does this and more behind the scenes for you. +
-### What about variable expansion? +
+What about variable expansion? Try [dotenv-expand](https://github.com/motdotla/dotenv-expand) +
-### What about syncing and securing .env files? +
+What about syncing and securing .env files? Use [dotenvx](https://github.com/dotenvx/dotenvx) to unlock syncing encrypted .env files over git. +
-### What if I accidentally commit my `.env` file to code? +
+What if I accidentally commit my `.env` file to code? Remove it, [remove git history](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository) and then install the [git pre-commit hook](https://github.com/dotenvx/dotenvx#pre-commit) to prevent this from ever happening again. @@ -721,8 +744,10 @@ Remove it, [remove git history](https://docs.github.com/en/authentication/keepin brew install dotenvx/brew/dotenvx dotenvx precommit --install ``` +
-### How can I prevent committing my `.env` file to a Docker build? +
+How can I prevent committing my `.env` file to a Docker build? Use the [docker prebuild hook](https://dotenvx.com/docs/features/prebuild). @@ -734,6 +759,7 @@ RUN curl -fsS https://dotenvx.sh/ | sh RUN dotenvx prebuild CMD ["dotenvx", "run", "--", "node", "index.js"] ``` +
## Contributing Guide From 8c92230c9793f6e8ce7bc3d5b9ca253dfa80c276 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:32:15 -0800 Subject: [PATCH 44/65] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 51da1852..482e1934 100644 --- a/README.md +++ b/README.md @@ -761,6 +761,8 @@ CMD ["dotenvx", "run", "--", "node", "index.js"] ```
+  + ## Contributing Guide See [CONTRIBUTING.md](CONTRIBUTING.md) From 155f0b5b9dae9f5fc676264ca3c11765e9151516 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:34:53 -0800 Subject: [PATCH 45/65] Sort FAQ by summary length --- README.md | 220 +++++++++++++++++++++++++++--------------------------- 1 file changed, 109 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index 482e1934..5a86b5be 100644 --- a/README.md +++ b/README.md @@ -534,17 +534,9 @@ Override any environment variables that have already been set. ## FAQ
-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](https://stackoverflow.com/questions/42335016/dotenv-file-is-not-loading-environment-variables). - -Turn on debug mode and try again.. - -```js -require('dotenv').config({ debug: true }) -``` +What about variable expansion? -You will receive a helpful error outputted to your console. +Try [dotenv-expand](https://github.com/motdotla/dotenv-expand)
@@ -556,6 +548,64 @@ passwords or API keys. Your production database should have a different password than your development database.
+
+How do I use dotenv with `import`? + +Simply.. + +```javascript +// 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](https://hacks.mozilla.org/2015/08/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`: +```js +class Client { + constructor (apiKey) { + console.log('apiKey', apiKey) + + this.apiKey = apiKey + } +} + +export default new Client(process.env.API_KEY) +``` +`index.mjs`: +```js +// 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.. + +```js +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](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-es6-import-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](https://github.com/motdotla/dotenv/issues/133#issuecomment-255298822) +
+
Should I have multiple `.env` files? @@ -566,6 +616,19 @@ We recommend creating one `.env` file per environment. Use `.env` for local/deve > – [The Twelve-Factor App](http://12factor.net/config)
+
+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: + +```js +const dotenv = require('dotenv') +const variableExpansion = require('dotenv-expand') +const myEnv = dotenv.config() +variableExpansion(myEnv) +``` +
+
What rules does the parsing engine follow? @@ -591,96 +654,71 @@ line'}
-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. +What about syncing and securing .env files? -```javascript -require('dotenv').config({ override: true }) -``` +Use [dotenvx](https://github.com/dotenvx/dotenvx) to unlock syncing encrypted .env files over git.
-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. +What if I accidentally commit my `.env` file to code? -If you are using [`react-scripts`](https://www.npmjs.com/package/react-scripts), which is distributed through [`create-react-app`](https://create-react-app.dev/), it has dotenv built in but with a quirk. Preface your environment variables with `REACT_APP_`. See [this stack overflow](https://stackoverflow.com/questions/42182577/is-it-possible-to-use-dotenv-in-a-react-project) for more details. +Remove it, [remove git history](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository) and then install the [git pre-commit hook](https://github.com/dotenvx/dotenvx#pre-commit) to prevent this from ever happening again. -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. +``` +brew install dotenvx/brew/dotenvx +dotenvx precommit --install +```
-Can I customize/write plugins for dotenv? +What happens to environment variables that were already set? -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: +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. -```js -const dotenv = require('dotenv') -const variableExpansion = require('dotenv-expand') -const myEnv = dotenv.config() -variableExpansion(myEnv) +If instead, you want to override `process.env` use the `override` option. + +```javascript +require('dotenv').config({ override: true }) ```
-How do I use dotenv with `import`? +How can I prevent committing my `.env` file to a Docker build? -Simply.. +Use the [docker prebuild hook](https://dotenvx.com/docs/features/prebuild). -```javascript -// index.mjs (ESM) -import 'dotenv/config' // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import -import express from 'express' +```bash +# Dockerfile +... +RUN curl -fsS https://dotenvx.sh/ | sh +... +RUN dotenvx prebuild +CMD ["dotenvx", "run", "--", "node", "index.js"] ``` +
-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](https://hacks.mozilla.org/2015/08/es6-in-depth-modules/) - -What does this mean in plain language? It means you would think the following would work but it won't. +
+How come my environment variables are not showing up for React? -`errorReporter.mjs`: -```js -class Client { - constructor (apiKey) { - console.log('apiKey', apiKey) +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. - this.apiKey = apiKey - } -} +If you are using [`react-scripts`](https://www.npmjs.com/package/react-scripts), which is distributed through [`create-react-app`](https://create-react-app.dev/), it has dotenv built in but with a quirk. Preface your environment variables with `REACT_APP_`. See [this stack overflow](https://stackoverflow.com/questions/42182577/is-it-possible-to-use-dotenv-in-a-react-project) for more details. -export default new Client(process.env.API_KEY) -``` -`index.mjs`: -```js -// Note: this is INCORRECT and will not work -import * as dotenv from 'dotenv' -dotenv.config() +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. +
-import errorReporter from './errorReporter.mjs' // process.env.API_KEY will be blank! -``` +
+Why is the `.env` file not loading my environment variables successfully? -`process.env.API_KEY` will be blank. +Most likely your `.env` file is not in the correct place. [See this stack overflow](https://stackoverflow.com/questions/42335016/dotenv-file-is-not-loading-environment-variables). -Instead, `index.mjs` should be written as.. +Turn on debug mode and try again.. ```js -import 'dotenv/config' - -import errorReporter from './errorReporter.mjs' +require('dotenv').config({ debug: true }) ``` -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](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-es6-import-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](https://github.com/motdotla/dotenv/issues/133#issuecomment-255298822) +You will receive a helpful error outputted to your console.
@@ -723,46 +761,6 @@ module.exports = { Alternatively, just use [dotenv-webpack](https://github.com/mrsteele/dotenv-webpack) which does this and more behind the scenes for you.
-
-What about variable expansion? - -Try [dotenv-expand](https://github.com/motdotla/dotenv-expand) -
- -
-What about syncing and securing .env files? - -Use [dotenvx](https://github.com/dotenvx/dotenvx) to unlock syncing encrypted .env files over git. -
- -
-What if I accidentally commit my `.env` file to code? - -Remove it, [remove git history](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository) and then install the [git pre-commit hook](https://github.com/dotenvx/dotenvx#pre-commit) to prevent this from ever happening again. - -``` -brew install dotenvx/brew/dotenvx -dotenvx precommit --install -``` -
- -
-How can I prevent committing my `.env` file to a Docker build? - -Use the [docker prebuild hook](https://dotenvx.com/docs/features/prebuild). - -```bash -# Dockerfile -... -RUN curl -fsS https://dotenvx.sh/ | sh -... -RUN dotenvx prebuild -CMD ["dotenvx", "run", "--", "node", "index.js"] -``` -
- -  - ## Contributing Guide See [CONTRIBUTING.md](CONTRIBUTING.md) From ebfb627a800624b91f9dbe9346191f07529e8f86 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:40:09 -0800 Subject: [PATCH 46/65] update README --- README.md | 61 ++++++++++++++++++++++--------------------------------- 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 5a86b5be..9e706234 100644 --- a/README.md +++ b/README.md @@ -533,23 +533,21 @@ Override any environment variables that have already been set. ## FAQ -
-What about variable expansion? +
What about variable expansion?
Try [dotenv-expand](https://github.com/motdotla/dotenv-expand) -
-
-Should I commit my `.env` file? +
+
Should I commit my `.env` file?
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. -
-
-How do I use dotenv with `import`? +
+
How do I use dotenv with `import`?
Simply.. @@ -606,8 +604,7 @@ There are two alternatives to this approach: 2. Create a separate file that will execute `config` first as outlined in [this comment on #133](https://github.com/motdotla/dotenv/issues/133#issuecomment-255298822)
-
-Should I have multiple `.env` files? +
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. @@ -615,9 +612,7 @@ We recommend creating one `.env` file per environment. Use `.env` for local/deve > > – [The Twelve-Factor App](http://12factor.net/config)
- -
-Can I customize/write plugins for dotenv? +
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: @@ -628,9 +623,7 @@ const myEnv = dotenv.config() variableExpansion(myEnv) ```
- -
-What rules does the parsing engine follow? +
What rules does the parsing engine follow?
The parsing engine currently supports the following rules: @@ -651,16 +644,14 @@ line'} ``` - backticks are supported (`` BACKTICK_KEY=`This has 'single' and "double" quotes inside of it.` ``) -
-
-What about syncing and securing .env files? +
+
What about syncing and securing .env files?
Use [dotenvx](https://github.com/dotenvx/dotenvx) to unlock syncing encrypted .env files over git. -
-
-What if I accidentally commit my `.env` file to code? +
+
What if I accidentally commit my `.env` file to code?
Remove it, [remove git history](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository) and then install the [git pre-commit hook](https://github.com/dotenvx/dotenvx#pre-commit) to prevent this from ever happening again. @@ -668,10 +659,9 @@ Remove it, [remove git history](https://docs.github.com/en/authentication/keepin brew install dotenvx/brew/dotenvx dotenvx precommit --install ``` -
-
-What happens to environment variables that were already set? +
+
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. @@ -680,10 +670,9 @@ If instead, you want to override `process.env` use the `override` option. ```javascript require('dotenv').config({ override: true }) ``` -
-
-How can I prevent committing my `.env` file to a Docker build? +
+
How can I prevent committing my `.env` file to a Docker build?
Use the [docker prebuild hook](https://dotenvx.com/docs/features/prebuild). @@ -695,20 +684,18 @@ 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? +
+
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`](https://www.npmjs.com/package/react-scripts), which is distributed through [`create-react-app`](https://create-react-app.dev/), it has dotenv built in but with a quirk. Preface your environment variables with `REACT_APP_`. See [this stack overflow](https://stackoverflow.com/questions/42182577/is-it-possible-to-use-dotenv-in-a-react-project) 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? +
+
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](https://stackoverflow.com/questions/42335016/dotenv-file-is-not-loading-environment-variables). @@ -719,10 +706,9 @@ 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'`? +
+
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: @@ -759,6 +745,7 @@ module.exports = { ``` Alternatively, just use [dotenv-webpack](https://github.com/mrsteele/dotenv-webpack) which does this and more behind the scenes for you. +
## Contributing Guide From 762826c2525f52114b2402508ed7fec2ca56412c Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:40:30 -0800 Subject: [PATCH 47/65] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9e706234..c9118031 100644 --- a/README.md +++ b/README.md @@ -748,6 +748,8 @@ Alternatively, just use [dotenv-webpack](https://github.com/mrsteele/dotenv-webp
+  + ## Contributing Guide See [CONTRIBUTING.md](CONTRIBUTING.md) From 691509a9160e3d1f8eb6584451b0405a79184f2f Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:43:25 -0800 Subject: [PATCH 48/65] update README --- README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c9118031..6aabc844 100644 --- a/README.md +++ b/README.md @@ -533,18 +533,16 @@ Override any environment variables that have already been set. ## FAQ -
What about variable expansion?
+
Should I commit my `.env` file?
-Try [dotenv-expand](https://github.com/motdotla/dotenv-expand) +No. -
-
Should I commit my `.env` file?
+Unless you encrypt it with [dotenvx](https://github.com/dotenvx/dotenvx). Then we recommend you do. -No. We **strongly** recommend against committing your `.env` file to version +
+
What about variable expansion?
-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. +Use [dotenvx](https://github.com/dotenvx/dotenvx).
How do I use dotenv with `import`?
@@ -611,6 +609,9 @@ We recommend creating one `.env` file per environment. Use `.env` for local/deve > 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](http://12factor.net/config) + +Additionally, we recommend using [dotenvx](https://github.com/dotenvx/dotenvx) to encrypt and manage these. +
Can I customize/write plugins for dotenv?
@@ -622,6 +623,7 @@ const variableExpansion = require('dotenv-expand') const myEnv = dotenv.config() variableExpansion(myEnv) ``` +
What rules does the parsing engine follow?
@@ -656,7 +658,7 @@ Use [dotenvx](https://github.com/dotenvx/dotenvx) to unlock syncing encrypted .e Remove it, [remove git history](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository) and then install the [git pre-commit hook](https://github.com/dotenvx/dotenvx#pre-commit) to prevent this from ever happening again. ``` -brew install dotenvx/brew/dotenvx +npm i -g @dotenvx/dotenvx dotenvx precommit --install ``` From a98ba5699fbf6234b133531198bbcea433d8f498 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:44:09 -0800 Subject: [PATCH 49/65] update README --- README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 6aabc844..0a41266e 100644 --- a/README.md +++ b/README.md @@ -545,6 +545,18 @@ Unless you encrypt it with [dotenvx](https://github.com/dotenvx/dotenvx). Then w Use [dotenvx](https://github.com/dotenvx/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](http://12factor.net/config) + +Additionally, we recommend using [dotenvx](https://github.com/dotenvx/dotenvx) to encrypt and manage these. + +
+
How do I use dotenv with `import`?
Simply.. @@ -602,17 +614,6 @@ There are two alternatives to this approach: 2. Create a separate file that will execute `config` first as outlined in [this comment on #133](https://github.com/motdotla/dotenv/issues/133#issuecomment-255298822)
-
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](http://12factor.net/config) - -Additionally, we recommend using [dotenvx](https://github.com/dotenvx/dotenvx) to encrypt and manage these. - -
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: From 3fcd2fe35d86a930ca74aa905b53f4dc0091e868 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:45:28 -0800 Subject: [PATCH 50/65] update README --- README.md | 369 ++++++++++++++++++++++++++---------------------------- 1 file changed, 181 insertions(+), 188 deletions(-) diff --git a/README.md b/README.md index 0a41266e..95ecc1a9 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,6 @@ 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 @@ -346,191 +345,6 @@ vestauth agent curl https://as2.dotenvx.com/get?key=KEY   -## Documentation - -Dotenv exposes four functions: - -* `config` -* `parse` -* `populate` - -### Config - -`config` will read your `.env` file, parse the contents, assign it to -[`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env), -and return an Object with a `parsed` key containing the loaded content or an `error` key if it failed. - -```js -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. - -```js -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. - -```js -require('dotenv').config({ path: ['.env.local', '.env'] }) -``` - -##### quiet - -Default: `false` - -Suppress runtime logging message. - -```js -// index.js -require('dotenv').config({ quiet: false }) // change to true to suppress -console.log(`Hello ${process.env.HELLO}`) -``` - -```ini -# .env -HELLO=World -``` - -```sh -$ 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. - -```js -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. - -```js -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. - -```js -require('dotenv').config({ override: true }) -``` - -##### processEnv - -Default: `process.env` - -Specify an object to write your environment variables to. Defaults to `process.env` environment variables. - -```js -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. - -```js -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. - -```js -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: - -```js -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: - -```js -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. - -  - ## FAQ
Should I commit my `.env` file?
@@ -753,9 +567,188 @@ Alternatively, just use [dotenv-webpack](https://github.com/mrsteele/dotenv-webp   -## Contributing Guide +## Docs + +Dotenv exposes four functions: + +* `config` +* `parse` +* `populate` + +### Config + +`config` will read your `.env` file, parse the contents, assign it to +[`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env), +and return an Object with a `parsed` key containing the loaded content or an `error` key if it failed. + +```js +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. + +```js +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. + +```js +require('dotenv').config({ path: ['.env.local', '.env'] }) +``` + +##### quiet + +Default: `false` + +Suppress runtime logging message. + +```js +// index.js +require('dotenv').config({ quiet: false }) // change to true to suppress +console.log(`Hello ${process.env.HELLO}`) +``` + +```ini +# .env +HELLO=World +``` + +```sh +$ 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. + +```js +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. + +```js +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. + +```js +require('dotenv').config({ override: true }) +``` + +##### processEnv + +Default: `process.env` + +Specify an object to write your environment variables to. Defaults to `process.env` environment variables. + +```js +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. + +```js +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' } +``` -See [CONTRIBUTING.md](CONTRIBUTING.md) +#### Options + +##### debug + +Default: `false` + +Turn on logging to help debug why certain keys or values are not being set as you expect. + +```js +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: + +```js +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: + +```js +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.   From 75a36f991829192cec130e0fea60911a69c90ca5 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:49:08 -0800 Subject: [PATCH 51/65] update README --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 95ecc1a9..aa47e1de 100644 --- a/README.md +++ b/README.md @@ -318,13 +318,15 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari ## Agents -AS2 is agentic secret storage from Dotenvx. - -> Secrets designed for agents. No logins. No consoles. Pure cryptography. +> If you are doing agentic coding you need: +> 1. A way for secrets to travel with your agent +> 2. A way for your agent to access them without juggling API Keys and OAuth tokens. +> +> Plaintext `.env` files are not a good solution for this. Instead, use [dotenvx as2](https://dotenvx.com/as2). ### Quickstart -Install vestauth and initialize your agent. (AS2 uses vestauth to authenticate agents.) +Install vestauth and initialize your agent. ```bash npm i -g vestauth From 2690d67cc3a4c4202391a1e3072b371b09de0136 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:57:42 -0800 Subject: [PATCH 52/65] update README --- README.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index aa47e1de..6b25081b 100644 --- a/README.md +++ b/README.md @@ -318,13 +318,9 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari ## Agents -> If you are doing agentic coding you need: -> 1. A way for secrets to travel with your agent -> 2. A way for your agent to access them without juggling API Keys and OAuth tokens. -> -> Plaintext `.env` files are not a good solution for this. Instead, use [dotenvx as2](https://dotenvx.com/as2). - -### Quickstart +> Software is changing, and dotenv must change with it—that is why we built [dotenvx as2](https://dotenvx.com/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. +> +> If you are writing agentic code here is how to get started: Install vestauth and initialize your agent. @@ -333,13 +329,13 @@ npm i -g vestauth vestauth agent init ``` -Your agent can `set` secrets: +Your agent can `set` secrets in as2: ```bash vestauth agent curl -X POST https://as2.dotenvx.com/set '{"KEY":"value"}' ``` -Your agent can `get` secrets: +And your agent can `get` secrets: ```bash vestauth agent curl https://as2.dotenvx.com/get?key=KEY From 5d323d228fc59784ebc87c78ed44b23cdeab8b81 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 11:59:24 -0800 Subject: [PATCH 53/65] update README --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6b25081b..91ba6f42 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ console.log(typeof config, config) // object { BASIC : 'basic' } > Note: Consider using [`dotenvx`](https://github.com/dotenvx/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](https://github.com/motdotla) +> 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](https://mot.la) You can use the `--require` (`-r`) [command line option](https://nodejs.org/api/cli.html#-r---require-module) to preload dotenv. By doing this, you do not need to require and load dotenv in your application code. @@ -318,9 +318,8 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari ## Agents -> Software is changing, and dotenv must change with it—that is why we built [dotenvx as2](https://dotenvx.com/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. -> -> If you are writing agentic code here is how to get started: +> Software is changing, and dotenv must change with it—that is why I built [agentic secret stoarge (AS2)](https://dotenvx.com/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. - [motdotla](https://mot.la) +> Install vestauth and initialize your agent. From 241fee789ef54b1207876156fe45521a3c50757a Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 12:00:48 -0800 Subject: [PATCH 54/65] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 91ba6f42..080b4de2 100644 --- a/README.md +++ b/README.md @@ -318,6 +318,8 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari ## Agents +dotenvx-as2 + > Software is changing, and dotenv must change with it—that is why I built [agentic secret stoarge (AS2)](https://dotenvx.com/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. - [motdotla](https://mot.la) > From 31add7c046888a71681c382cc81a216b738f8b20 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 12:01:05 -0800 Subject: [PATCH 55/65] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 080b4de2..3c7b149d 100644 --- a/README.md +++ b/README.md @@ -318,7 +318,7 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari ## Agents -dotenvx-as2 +dotenvx-as2 > Software is changing, and dotenv must change with it—that is why I built [agentic secret stoarge (AS2)](https://dotenvx.com/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. - [motdotla](https://mot.la) > From 23bd017381f1ab5e4fcdeaebe2e134aaef644a4c Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 12:02:04 -0800 Subject: [PATCH 56/65] update README --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c7b149d..9ed448dd 100644 --- a/README.md +++ b/README.md @@ -320,7 +320,11 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari dotenvx-as2 -> Software is changing, and dotenv must change with it—that is why I built [agentic secret stoarge (AS2)](https://dotenvx.com/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. - [motdotla](https://mot.la) +> Software is changing, and dotenv must change with it—that is why I built [agentic secret stoarge (AS2)](https://dotenvx.com/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](https://github.com/vestauth/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. - [motdotla](https://mot.la) > Install vestauth and initialize your agent. From 6351887077957c5ee74c3528bccbf5512b184b2e Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 12:03:04 -0800 Subject: [PATCH 57/65] update README --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9ed448dd..c0d0a3ab 100644 --- a/README.md +++ b/README.md @@ -324,8 +324,11 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari > > 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](https://github.com/vestauth/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. - [motdotla](https://mot.la) +> It is backed by [Vestauth](https://github.com/vestauth/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](https://mot.la) + +### Quickstart Install vestauth and initialize your agent. From 485695052c82c26024fbb8568babb0770756dd06 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 12:07:04 -0800 Subject: [PATCH 58/65] update README --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c0d0a3ab..2a08785b 100644 --- a/README.md +++ b/README.md @@ -330,25 +330,28 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari ### Quickstart -Install vestauth and initialize your agent. +Install vestauth and initialize your agent. ```bash npm i -g vestauth + vestauth agent init ``` -Your agent can `set` secrets in as2: +Your agent `set`s secrets with a simple `curl` endpoint: ```bash vestauth agent curl -X POST https://as2.dotenvx.com/set '{"KEY":"value"}' ``` -And your agent can `get` secrets: +And your agent `get`s secrets with a simple `curl` endpoint: ```bash 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 From dec94ad828acba99e3a8570ecf12a1081f9c189c Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 12:08:02 -0800 Subject: [PATCH 59/65] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2a08785b..0cb5c687 100644 --- a/README.md +++ b/README.md @@ -350,7 +350,7 @@ And your agent `get`s 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. +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.   From f61f3832c438078fc5d6552f59fac0c0205eca98 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 12:12:04 -0800 Subject: [PATCH 60/65] =?UTF-8?q?changelog=20=F0=9F=AA=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06ff71d1..d59aff45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,17 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. -## [Unreleased](https://github.com/motdotla/dotenv/compare/v17.2.4...master) +## [Unreleased](https://github.com/motdotla/dotenv/compare/v17.3.0...master) + +## [17.3.0](https://github.com/motdotla/dotenv/compare/v17.2.4...v17.3.0) (2026-02-12) + +### Added + +* Add a new README section on dotenv’s approach to the agentic future. + +### Changed + +* Rewrite README to get humans started more quickly with less noise while simultaneously making more accessible for llms and agents to go deeper into details. ## [17.2.4](https://github.com/motdotla/dotenv/compare/v17.2.3...v17.2.4) (2026-02-05) From 5febe352d4dd499bfaa73de808a56bf03a268b6b Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 12:13:19 -0800 Subject: [PATCH 61/65] 17.3.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a8fdab9e..30ecba7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dotenv", - "version": "17.2.4", + "version": "17.3.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "dotenv", - "version": "17.2.4", + "version": "17.3.0", "license": "BSD-2-Clause", "devDependencies": { "@types/node": "^18.11.3", diff --git a/package.json b/package.json index 9e2f33bc..b61d6fa4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dotenv", - "version": "17.2.4", + "version": "17.3.0", "description": "Loads environment variables from .env file", "main": "lib/main.js", "types": "lib/main.d.ts", From b6d7339fd085a290669af8e601331c13b4dd2920 Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 12:51:38 -0800 Subject: [PATCH 62/65] fix spelling --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cb5c687..abfe5698 100644 --- a/README.md +++ b/README.md @@ -320,7 +320,7 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari dotenvx-as2 -> Software is changing, and dotenv must change with it—that is why I built [agentic secret stoarge (AS2)](https://dotenvx.com/as2). Agents run code without humans at terminals, so plaintext `.env` files are the wrong primitive. +> Software is changing, and dotenv must change with it—that is why I built [agentic secret storage (AS2)](https://dotenvx.com/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. > From 6379eb2cae43c27656df8d93509b2c14366811ec Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 13:37:10 -0800 Subject: [PATCH 63/65] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index abfe5698..b82a4381 100644 --- a/README.md +++ b/README.md @@ -341,7 +341,7 @@ vestauth agent init Your agent `set`s secrets with a simple `curl` endpoint: ```bash -vestauth agent curl -X POST https://as2.dotenvx.com/set '{"KEY":"value"}' +vestauth agent curl -X POST https://as2.dotenvx.com/set -d '{"KEY":"value"}' ``` And your agent `get`s secrets with a simple `curl` endpoint: From 27303fd56321a166d698f0482e0f4d0c51e51c1e Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 14:09:35 -0800 Subject: [PATCH 64/65] update README-es --- CHANGELOG.md | 8 +- README-es.md | 788 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 592 insertions(+), 204 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d59aff45..c3d6a9c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. -## [Unreleased](https://github.com/motdotla/dotenv/compare/v17.3.0...master) +## [Unreleased](https://github.com/motdotla/dotenv/compare/v17.3.1...master) + +## [17.3.1](https://github.com/motdotla/dotenv/compare/v17.3.0...v17.3.1) (2026-02-12) + +### Changed + +* Fix as2 example command in README and update spanish README ## [17.3.0](https://github.com/motdotla/dotenv/compare/v17.2.4...v17.3.0) (2026-02-12) diff --git a/README-es.md b/README-es.md index 06214611..441160c3 100644 --- a/README-es.md +++ b/README-es.md @@ -1,67 +1,96 @@ -
-🎉 new announcement vestauth: auth for agents–from the creator of dotenv and dotenvx. -
+# dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) [![downloads](https://img.shields.io/npm/dw/dotenv)](https://www.npmjs.com/package/dotenv) -  +dotenv -# dotenv [![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) +Dotenv is a zero-dependency module that loads environment variables from a `.env` file into [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). Storing configuration in the environment separate from code is based on [The Twelve-Factor App](https://12factor.net/config) methodology. -dotenv +[Watch the tutorial](https://www.youtube.com/watch?v=YtkZR0NFd1g) -Dotenv es un módulo de dependencia cero que carga las variables de entorno desde un archivo `.env` en [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env). El almacenamiento de la configuración del entorno separado del código está basado en la metodología [The Twelve-Factor App](http://12factor.net/config). +  -[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard) -[![LICENSE](https://img.shields.io/github/license/motdotla/dotenv.svg)](LICENSE) +## Usage -## Instalación +Install it. -```bash -# instalación local (recomendado) +```sh npm install dotenv --save ``` -O installación con yarn? `yarn add dotenv` - -## Uso +Create a `.env` file in the root of your project: -Cree un archivo `.env` en la raíz de su proyecto: - -```dosini +```ini +# .env S3_BUCKET="YOURS3BUCKET" SECRET_KEY="YOURSECRETKEYGOESHERE" ``` -Tan prónto como sea posible en su aplicación, importe y configure dotenv: +And as early as possible in your application, import and configure dotenv: ```javascript -require('dotenv').config() -console.log(process.env) // elimine esto después que haya confirmado que esta funcionando +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 ``` -.. o usa ES6? +That's it. `process.env` now has the keys and values you defined in your `.env` file: + +  + +## Advanced + +
ES6
+ +Import with [ES6](#how-do-i-use-dotenv-with-import): ```javascript -import * as dotenv from 'dotenv' // vea en https://github.com/motdotla/dotenv#como-uso-dotenv-con-import -// REVISAR LINK DE REFERENCIA DE IMPORTACIÓN -dotenv.config() -import express from 'express' +import 'dotenv/config' ``` -Eso es todo. `process.env` ahora tiene las claves y los valores que definiste en tu archivo `.env`: +ES6 import if you need to set config options: ```javascript -require('dotenv').config() +import dotenv from 'dotenv' +dotenv.config({ path: '/custom/path/to/.env' }) +``` -... +
+
bun
+ +```sh +bun add dotenv +``` + +
+
yarn
+ +```sh +yarn add dotenv +``` + +
+
pnpm
+ +```sh +pnpm add dotenv +``` -s3.getBucketCors({Bucket: process.env.S3_BUCKET}, function(err, data) {}) +
+
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. + +```ini +# app/backend/.env +S3_BUCKET="YOURS3BUCKET" +SECRET_KEY="YOURSECRETKEYGOESHERE" ``` -### Valores multilínea +
+
Multiline Values
-Si necesita variables de varias líneas, por ejemplo, claves privadas, ahora se admiten en la versión (`>= v15.0.0`) con saltos de línea: +If you need multiline variables, for example private keys, those are now supported (`>= v15.0.0`) with line breaks: -```dosini +```ini PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY----- ... Kh9NV... @@ -69,324 +98,677 @@ Kh9NV... -----END RSA PRIVATE KEY-----" ``` -Alternativamente, puede usar comillas dobles y usar el carácter `\n`: +Alternatively, you can double quote strings and use the `\n` character: -```dosini +```ini PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END RSA PRIVATE KEY-----\n" ``` -### Comentarios +
+
Comments
-Los comentarios pueden ser agregados en tu archivo o en la misma línea: +Comments may be added to your file on their own line or inline: -```dosini +```ini # This is a comment SECRET_KEY=YOURSECRETKEYGOESHERE # comment SECRET_HASH="something-with-a-#-hash" ``` -Los comentarios comienzan donde existe un `#`, entonces, si su valor contiene un `#`, enciérrelo entre comillas. Este es un cambio importante desde la versión `>= v15.0.0` en adelante. +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. -### Análisis +
+
Parsing
-El motor que analiza el contenido de su archivo que contiene variables de entorno está disponible para su uso. Este Acepta una Cadena o un Búfer y devolverá un Objeto con las claves y los valores analizados. +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. ```javascript const dotenv = require('dotenv') -const buf = Buffer.from('BASICO=basico') -const config = dotenv.parse(buf) // devolverá un objeto -console.log(typeof config, config) // objeto { BASICO : 'basico' } +const buf = Buffer.from('BASIC=basic') +const config = dotenv.parse(buf) // will return an object +console.log(typeof config, config) // object { BASIC : 'basic' } ``` -### Precarga +
+
Preload
-Puede usar el `--require` (`-r`) [opción de línea de comando](https://nodejs.org/api/cli.html#-r---require-module) para precargar dotenv. Al hacer esto, no necesita requerir ni cargar dotnev en el código de su aplicación. +> Note: Consider using [`dotenvx`](https://github.com/dotenvx/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](https://mot.la) + +You can use the `--require` (`-r`) [command line option](https://nodejs.org/api/cli.html#-r---require-module) to preload dotenv. By doing this, you do not need to require and load dotenv in your application code. ```bash -$ node -r dotenv/config tu_script.js +$ node -r dotenv/config your_script.js ``` -Las opciones de configuración a continuación se admiten como argumentos de línea de comandos en el formato `dotenv_config_
+
Variable Expansion
-Necesitaras agregar el valor de otro variable en una de sus variables? Usa [dotenv-expand](https://github.com/motdotla/dotenv-expand). +Use [dotenvx](https://github.com/dotenvx/dotenvx) for variable expansion. -## Ejemplos +Reference and expand variables already on your machine for use in your .env file. -Vea [ejemplos](https://github.com/dotenv-org/examples) sobre el uso de dotenv con varios frameworks, lenguajes y configuraciones. +```ini +# .env +USERNAME="username" +DATABASE_URL="postgres://${USERNAME}@localhost/my_database" +``` +```js +// index.js +console.log('DATABASE_URL', process.env.DATABASE_URL) +``` +```sh +$ dotenvx run --debug -- node index.js +[dotenvx@0.14.1] injecting env (2) from .env +DATABASE_URL postgres://username@localhost/my_database +``` -* [nodejs](https://github.com/dotenv-org/examples/tree/master/dotenv-nodejs) -* [nodejs (depurar en)](https://github.com/dotenv-org/examples/tree/master/dotenv-nodejs-debug) -* [nodejs (anular en)](https://github.com/dotenv-org/examples/tree/master/dotenv-nodejs-override) -* [esm](https://github.com/dotenv-org/examples/tree/master/dotenv-esm) -* [esm (precarga)](https://github.com/dotenv-org/examples/tree/master/dotenv-esm-preload) -* [typescript](https://github.com/dotenv-org/examples/tree/master/dotenv-typescript) -* [typescript parse](https://github.com/dotenv-org/examples/tree/master/dotenv-typescript-parse) -* [typescript config](https://github.com/dotenv-org/examples/tree/master/dotenv-typescript-config) -* [webpack](https://github.com/dotenv-org/examples/tree/master/dotenv-webpack) -* [webpack (plugin)](https://github.com/dotenv-org/examples/tree/master/dotenv-webpack2) -* [react](https://github.com/dotenv-org/examples/tree/master/dotenv-react) -* [react (typescript)](https://github.com/dotenv-org/examples/tree/master/dotenv-react-typescript) -* [express](https://github.com/dotenv-org/examples/tree/master/dotenv-express) -* [nestjs](https://github.com/dotenv-org/examples/tree/master/dotenv-nestjs) +
+
Command Substitution
-## Documentación +Use [dotenvx](https://github.com/dotenvx/dotenvx) for command substitution. -Dotenv expone dos funciones: +Add the output of a command to one of your variables in your .env file. -* `configuración` -* `analizar` +```ini +# .env +DATABASE_URL="postgres://$(whoami)@localhost/my_database" +``` +```js +// index.js +console.log('DATABASE_URL', process.env.DATABASE_URL) +``` +```sh +$ dotenvx run --debug -- node index.js +[dotenvx@0.14.1] injecting env (1) from .env +DATABASE_URL postgres://yourusername@localhost/my_database +``` -### Configuración +
+
Encryption
-`Configuración` leerá su archivo `.env`, analizará el contenido, lo asignará a [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env), -y devolverá un Objeto con una clave `parsed` que contiene el contenido cargado o una clave `error` si falla. +Use [dotenvx](https://github.com/dotenvx/dotenvx) for encryption. -```js -const result = dotenv.config() +Add encryption to your `.env` files with a single command. -if (result.error) { - throw result.error -} +``` +$ dotenvx set HELLO Production -f .env.production +$ echo "console.log('Hello ' + process.env.HELLO)" > index.js -console.log(result.parsed) +$ DOTENV_PRIVATE_KEY_PRODUCTION="<.env.production private key>" dotenvx run -- node index.js +[dotenvx] injecting env (2) from .env.production +Hello Production ``` -Adicionalmente, puede pasar opciones a `configuracion`. +[learn more](https://github.com/dotenvx/dotenvx?tab=readme-ov-file#encryption) -#### Opciones +
+
Multiple Environments
-##### Ruta +Use [dotenvx](https://github.com/dotenvx/dotenvx) to manage multiple environments. -Por defecto: `path.resolve(process.cwd(), '.env')` +Run any environment locally. Create a `.env.ENVIRONMENT` file and use `-f` to load it. It's straightforward, yet flexible. -Especifique una ruta personalizada si el archivo que contiene las variables de entorno se encuentra localizado en otro lugar. +```bash +$ echo "HELLO=production" > .env.production +$ echo "console.log('Hello ' + process.env.HELLO)" > index.js -```js -require('dotenv').config({ path: '/personalizado/ruta/a/.env' }) +$ dotenvx run -f=.env.production -- node index.js +Hello production +> ^^ ``` -##### Codificación +or with multiple .env files + +```bash +$ echo "HELLO=local" > .env.local +$ echo "HELLO=World" > .env +$ echo "console.log('Hello ' + process.env.HELLO)" > index.js -Por defecto: `utf8` +$ dotenvx run -f=.env.local -f=.env -- node index.js +Hello local +``` -Especifique la codificación del archivo que contiene las variables de entorno. +[more environment examples](https://dotenvx.com/docs/quickstart/environments) -```js -require('dotenv').config({ encoding: 'latin1' }) +
+
Production
+ +Use [dotenvx](https://github.com/dotenvx/dotenvx) for production deploys. + +Create a `.env.production` file. + +```sh +$ echo "HELLO=production" > .env.production ``` -##### Depurar +Encrypt it. -Por defecto: `false` +```sh +$ dotenvx encrypt -f .env.production +``` -Active el registro de ayuda para depurar por qué ciertas claves o valores no se inician como lo esperabas. +Set `DOTENV_PRIVATE_KEY_PRODUCTION` (found in `.env.keys`) on your server. -```js -require('dotenv').config({ debug: process.env.DEBUG }) +``` +$ heroku config:set DOTENV_PRIVATE_KEY_PRODUCTION=value ``` -##### Anular +Commit your `.env.production` file to code and deploy. -Por defecto: `false` +``` +$ 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](https://github.com/dotenvx/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](https://github.com/dotenv-org/examples) of using dotenv with various frameworks, languages, and configurations. + +* [nodejs](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nodejs) +* [nodejs (debug on)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nodejs-debug) +* [nodejs (override on)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nodejs-override) +* [nodejs (processEnv override)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-custom-target) +* [esm](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-esm) +* [esm (preload)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-esm-preload) +* [typescript](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-typescript) +* [typescript parse](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-typescript-parse) +* [typescript config](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-typescript-config) +* [webpack](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-webpack) +* [webpack (plugin)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-webpack2) +* [react](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-react) +* [react (typescript)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-react-typescript) +* [express](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-express) +* [nestjs](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nestjs) +* [fastify](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-fastify) + +
+ +  + +## Agentes + +dotenvx-as2 + +> El software está cambiando, y dotenv debe cambiar con él—por eso construí [agentic secret storage (AS2)](https://dotenvx.com/as2). Los agentes ejecutan código sin humanos en la terminal, por lo que los archivos `.env` en texto plano son el primitivo equivocado. +> +> AS2 está diseñado para software autónomo: cifrado por defecto, cero acceso a consola y entrega priorizando la criptografía que mantiene a los operadores fuera del circuito. +> +> Está respaldado por [Vestauth](https://github.com/vestauth/vestauth), la capa de autenticación pionera y de confianza para agentes—que otorga a cada agente una identidad criptográfica para firmar solicitudes con claves privadas y verificarlas con claves públicas. Sin secretos compartidos que se filtren. +> +> Es lo que uso ahora. - [motdotla](https://mot.la) + +### Inicio rápido + +Instala vestauth e inicializa tu agente. + +```bash +npm i -g vestauth + +vestauth agent init +``` + +Tu agente puede `set` secretos con un endpoint `curl` simple: + +```bash +vestauth agent curl -X POST https://as2.dotenvx.com/set -d '{"KEY":"value"}' +``` + +Y tu agente puede `get` secretos con un endpoint `curl` simple: -Anule cualquier variable de entorno que ya se haya configurada en su maquina con los valores de su archivo .env. +```bash +vestauth agent curl https://as2.dotenvx.com/get?key=KEY +``` +¡Eso es todo! Este nuevo primitivo habilita el acceso a secretos para agentes sin intervención humana, flujos de OAuth ni claves API. Es el futuro para los agentes. + +  + +## FAQ + +
Should I commit my `.env` file?
+ +No. + +Unless you encrypt it with [dotenvx](https://github.com/dotenvx/dotenvx). Then we recommend you do. + +
+
What about variable expansion?
+ +Use [dotenvx](https://github.com/dotenvx/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](http://12factor.net/config) + +Additionally, we recommend using [dotenvx](https://github.com/dotenvx/dotenvx) to encrypt and manage these. + +
+ +
How do I use dotenv with `import`?
+ +Simply.. + +```javascript +// 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](https://hacks.mozilla.org/2015/08/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`: ```js -require('dotenv').config({ override: true }) +class Client { + constructor (apiKey) { + console.log('apiKey', apiKey) + + this.apiKey = apiKey + } +} + +export default new Client(process.env.API_KEY) +``` +`index.mjs`: +```js +// 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! ``` -### Analizar +`process.env.API_KEY` will be blank. -El motor que analiza el contenido del archivo que contiene las variables de entorno está disponible para su uso. Acepta una Cadena o un Búfer y retornará un objecto con los valores analizados. +Instead, `index.mjs` should be written as.. ```js -const dotenv = require('dotenv') -const buf = Buffer.from('BASICO=basico') -const config = dotenv.parse(buf) // devolverá un objeto -console.log(typeof config, config) // objeto { BASICO : 'basico' } +import 'dotenv/config' + +import errorReporter from './errorReporter.mjs' ``` -#### Opciones +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](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-es6-import-pitfall). + +There are two alternatives to this approach: -##### Depurar +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](https://github.com/motdotla/dotenv/issues/133#issuecomment-255298822) +
-Por defecto: `false` +
Can I customize/write plugins for dotenv?
-Active el registro de ayuda para depurar por qué ciertas claves o valores no se inician como lo esperabas. +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: ```js const dotenv = require('dotenv') -const buf = Buffer.from('hola mundo') -const opt = { debug: true } -const config = dotenv.parse(buf, opt) -// espere por un mensaje de depuración porque el búfer no esta listo KEY=VAL +const variableExpansion = require('dotenv-expand') +const myEnv = dotenv.config() +variableExpansion(myEnv) ``` -## FAQ +
+
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`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/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](https://github.com/dotenvx/dotenvx) to unlock syncing encrypted .env files over git. + +
+
What if I accidentally commit my `.env` file to code?
+ +Remove it, [remove git history](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository) and then install the [git pre-commit hook](https://github.com/dotenvx/dotenvx#pre-commit) 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. -### ¿Por qué el archivo `.env` no carga mis variables de entorno correctamente? +```javascript +require('dotenv').config({ override: true }) +``` -Lo más probable es que su archivo `.env` no esté en el lugar correcto. [Vea este stack overflow](https://stackoverflow.com/questions/42335016/dotenv-file-is-not-loading-environment-variables). +
+
How can I prevent committing my `.env` file to a Docker build?
-Active el modo de depuración y vuelva a intentarlo... +Use the [docker prebuild hook](https://dotenvx.com/docs/features/prebuild). + +```bash +# 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`](https://www.npmjs.com/package/react-scripts), which is distributed through [`create-react-app`](https://create-react-app.dev/), it has dotenv built in but with a quirk. Preface your environment variables with `REACT_APP_`. See [this stack overflow](https://stackoverflow.com/questions/42182577/is-it-possible-to-use-dotenv-in-a-react-project) 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](https://stackoverflow.com/questions/42335016/dotenv-file-is-not-loading-environment-variables). + +Turn on debug mode and try again.. ```js require('dotenv').config({ debug: true }) ``` -Recibirá un error apropiado en su consola. +You will receive a helpful error outputted to your console. -### ¿Debo confirmar mi archivo `.env`? +
+
Why am I getting the error `Module not found: Error: Can't resolve 'crypto|os|path'`?
-No. Recomendamos **enfáticamente** no enviar su archivo `.env` a la versión de control. Solo debe incluir los valores especificos del entorno, como la base de datos, contraseñas o claves API. +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: -### ¿Debería tener multiples archivos `.env`? +```bash +npm install node-polyfill-webpack-plugin +``` -No. Recomendamos **enfáticamente** no tener un archivo `.env` "principal" y un archivo `.env` de "entorno" como `.env.test`. Su configuración debe variar entre implementaciones y no debe compartir valores entre entornos. +Configure your `webpack.config.js` to something like the following. -> En una Aplicación de Doce Factores, las variables de entorno son controles diferenciados, cada uno totalmente independiente a otras variables de entorno. Nunca se agrupan como "entornos", sino que se gestionan de manera independiente para cada despliegue. Este es un modelo que se escala sin problemas a medida que la aplicación se expande de forma natural en más despliegues a lo largo de su vida. -> -> – [La Apliación de los Doce Factores](https://12factor.net/es/) +```js +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](https://github.com/mrsteele/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`](https://nodejs.org/docs/latest/api/process.html#process_process_env), +and return an Object with a `parsed` key containing the loaded content or an `error` key if it failed. + +```js +const result = dotenv.config() + +if (result.error) { + throw result.error +} + +console.log(result.parsed) +``` + +You can additionally, pass options to `config`. + +#### Options -### ¿Qué reglas sigue el motor de análisis? +##### path -El motor de análisis actualmente admite las siguientes reglas: +Default: `path.resolve(process.cwd(), '.env')` -- `BASICO=basico` se convierte en `{BASICO: 'basico'}` -- las líneas vacías se saltan -- las líneas que comienzan con `#` se tratan como comentarios -- `#` marca el comienzo de un comentario (a menos que el valor esté entre comillas) -- valores vacíos se convierten en cadenas vacías (`VACIO=` se convierte en `{VACIO: ''}`) -- las comillas internas se mantienen (piensa en JSON) (`JSON={"foo": "bar"}` se convierte en `{JSON:"{\"foo\": \"bar\"}"`) -- los espacios en blanco se eliminan de ambos extremos de los valores no citanos (aprende más en [`trim`](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)) (`FOO= algo ` se convierte en `{FOO: 'algo'}`) -- los valores entre comillas simples y dobles se escapan (`CITA_SIMPLE='citado'` se convierte en `{CITA_SIMPLE: "citado"}`) -- los valores entre comillas simples y dobles mantienen los espacios en blanco en ambos extremos (`FOO=" algo "` se convierte en `{FOO: ' algo '}`) -- los valores entre comillas dobles expanden nuevas líneas (`MULTILINEA="nueva\nlínea"` se convierte en +Specify a custom path if your file containing environment variables is located elsewhere. +```js +require('dotenv').config({ path: '/custom/path/to/.env' }) ``` -{MULTILINEA: 'nueva -línea'} + +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. + +```js +require('dotenv').config({ path: ['.env.local', '.env'] }) ``` -- se admite la comilla simple invertida (`` SIGNO_ACENTO=`Esto tiene comillas 'simples' y "dobles" en su interior.` ``) +##### quiet -### ¿Qué sucede con las variables de entorno que ya estaban configuradas? +Default: `false` -Por defecto, nunca modificaremos ninguna variable de entorno que ya haya sido establecida. En particular, si hay una variable en su archivo `.env` que colisiona con una que ya existe en su entorno, entonces esa variable se omitirá. +Suppress runtime logging message. -Si por el contrario, quieres anular `process.env` utiliza la opción `override`. +```js +// index.js +require('dotenv').config({ quiet: false }) // change to true to suppress +console.log(`Hello ${process.env.HELLO}`) +``` -```javascript -require('dotenv').config({ override: true }) +```ini +# .env +HELLO=World ``` -### ¿Por qué mis variables de entorno no aparecen para React? +```sh +$ node index.js +[dotenv@17.0.0] injecting env (1) from .env +Hello World +``` + +##### encoding -Su código React se ejecuta en Webpack, donde el módulo `fs` o incluso el propio `process` global no son accesibles fuera-de-la-caja. El módulo `process.env` sólo puede ser inyectado a través de la configuración de Webpack. +Default: `utf8` -Si estás usando [`react-scripts`](https://www.npmjs.com/package/react-scripts), el cual se distribuye a través de [`create-react-app`](https://create-react-app.dev/), tiene dotenv incorporado pero con una singularidad. Escriba sus variables de entorno con `REACT_APP_`. Vea [este stack overflow](https://stackoverflow.com/questions/42182577/is-it-possible-to-use-dotenv-in-a-react-project) para más detalles. +Specify the encoding of your file containing environment variables. + +```js +require('dotenv').config({ encoding: 'latin1' }) +``` -Si estás utilizando otros frameworks (por ejemplo, Next.js, Gatsby...), debes consultar su documentación para saber cómo injectar variables de entorno en el cliente. +##### debug -### ¿Puedo personalizar/escribir plugins para dotenv? +Default: `false` -Sí! `dotenv.config()` devuelve un objeto que representa el archivo `.env` analizado. Esto te da todo lo que necesitas para poder establecer valores en `process.env`. Por ejemplo: +Turn on logging to help debug why certain keys or values are not being set as you expect. ```js -const dotenv = require('dotenv') -const variableExpansion = require('dotenv-expand') -const miEnv = dotenv.config() -variableExpansion(miEnv) +require('dotenv').config({ debug: process.env.DEBUG }) ``` -### Cómo uso dotnev con `import`? +##### override -Simplemente.. +Default: `false` -```javascript -// index.mjs (ESM) -import * as dotenv from 'dotenv' // vea https://github.com/motdotla/dotenv#como-uso-dotenv-con-import -dotenv.config() -import express from 'express' +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. + +```js +require('dotenv').config({ override: true }) ``` -Un poco de historia... +##### processEnv -> Cuando se ejecuta un módulo que contiene una sentencia `import`, los módulos que importa serán cargados primero, y luego se ejecuta cada bloque del módulo en un recorrido en profundidad del gráfico de dependencias, evitando los ciclos al saltarse todo lo que ya se ha ejecutado. -> -> – [ES6 en Profundidad: Módulos](https://hacks.mozilla.org/2015/08/es6-in-depth-modules/) +Default: `process.env` -¿Qué significa esto en lenguaje sencillo? Significa que se podrías pensar que lo siguiente funcionaría pero no lo hará. +Specify an object to write your environment variables to. Defaults to `process.env` environment variables. ```js -// notificarError.mjs -import { Cliente } from 'mejor-servicio-para-notificar-error' +const myObject = {} +require('dotenv').config({ processEnv: myObject }) -export default new Client(process.env.CLAVE_API) +console.log(myObject) // values from .env +console.log(process.env) // this was not changed or written to +``` -// index.mjs -import dotenv from 'dotenv' -dotenv.config() +### Parse -import notificarError from './notificarError.mjs' -notificarError.report(new Error('ejemplo documentado')) +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. + +```js +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' } ``` -`process.env.CLAVE_API` será vacio. +#### Options + +##### debug -En su lugar, el código anterior debe ser escrito como... +Default: `false` + +Turn on logging to help debug why certain keys or values are not being set as you expect. ```js -// notificarError.mjs -import { Cliente } from 'mejor-servicio-para-notificar-errores' +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 +``` -export default new Client(process.env.CLAVE_API) +### Populate -// index.mjs -import * as dotenv from 'dotenv' -dotenv.config() +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: -import notificarError from './notificarError.mjs' -notificarError.report(new Error('ejemplo documentado')) +```js +const dotenv = require('dotenv') +const parsed = { HELLO: 'world' } + +dotenv.populate(process.env, parsed) + +console.log(process.env.HELLO) // world ``` -¿Esto tiene algo de sentido? Esto es poco poco intuitivo, pero es como funciona la importación de módulos en ES6. Aquí hay un ejemplo [ejemplo práctico de esta trampa](https://github.com/dotenv-org/examples/tree/master/dotenv-es6-import-pitfall). +For example, customizing the source AND target: -Existen dos arternativas a este planteamiento: +```js +const dotenv = require('dotenv') +const parsed = { HELLO: 'universe' } +const target = { HELLO: 'world' } // empty object -1. Precarga dotenv: `node --require dotenv/config index.js` (_Nota: no es necesario usar `import` dotenv con este método_) -2. Cree un archivo separado que ejecutará `config` primero como se describe en [este comentario #133](https://github.com/motdotla/dotenv/issues/133#issuecomment-255298822) +dotenv.populate(target, parsed, { override: true, debug: true }) + +console.log(target) // { HELLO: 'universe' } +``` -### ¿Qué pasa con la expansión de variable? +#### options -Prueba [dotenv-expand](https://github.com/motdotla/dotenv-expand) +##### Debug -## Guía de contribución +Default: `false` -Vea [CONTRIBUTING.md](CONTRIBUTING.md) +Turn on logging to help debug why certain keys or values are not being populated as you expect. -## REGISTRO DE CAMBIOS +##### override -Vea [CHANGELOG.md](CHANGELOG.md) +Default: `false` + +Override any environment variables that have already been set. + +  + +## CHANGELOG + +See [CHANGELOG.md](CHANGELOG.md) + +  -## ¿Quiénes utilizan dotenv? +## Who's using dotenv? -[Estos módulos npm dependen de él.](https://www.npmjs.com/browse/depended/dotenv) +[These npm modules depend on it.](https://www.npmjs.com/browse/depended/dotenv) -Los proyectos que lo amplían suelen utilizar la [palabra clave "dotenv" en npm](https://www.npmjs.com/search?q=keywords:dotenv). +Projects that expand it often use the [keyword "dotenv" on npm](https://www.npmjs.com/search?q=keywords:dotenv). From 7bc16a41c9efd4cf4ab8a4614d0ace7fd240b27b Mon Sep 17 00:00:00 2001 From: Scott Motte Date: Thu, 12 Feb 2026 14:09:44 -0800 Subject: [PATCH 65/65] 17.3.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 30ecba7d..c44885c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dotenv", - "version": "17.3.0", + "version": "17.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "dotenv", - "version": "17.3.0", + "version": "17.3.1", "license": "BSD-2-Clause", "devDependencies": { "@types/node": "^18.11.3", diff --git a/package.json b/package.json index b61d6fa4..209912e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dotenv", - "version": "17.3.0", + "version": "17.3.1", "description": "Loads environment variables from .env file", "main": "lib/main.js", "types": "lib/main.d.ts",