@dotenvx/dotenvx 1.48.1 → 1.48.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -112,389 +112,389 @@ see [extended quickstart guide](https://dotenvx.com/docs/quickstart)
112
112
 
113
113
  More examples
114
114
 
115
- * <details><summary>TypeScript 📘</summary><br>
116
-
117
- ```json
118
- // package.json
119
- {
120
- "type": "module",
121
- "dependencies": {
122
- "chalk": "^5.3.0"
123
- }
115
+ <details><summary>TypeScript 📘</summary><br>
116
+
117
+ ```json
118
+ // package.json
119
+ {
120
+ "type": "module",
121
+ "dependencies": {
122
+ "chalk": "^5.3.0"
124
123
  }
125
- ```
124
+ }
125
+ ```
126
126
 
127
- ```js
128
- // index.ts
129
- import chalk from 'chalk'
130
- console.log(chalk.blue(`Hello ${process.env.HELLO}`))
131
- ```
127
+ ```js
128
+ // index.ts
129
+ import chalk from 'chalk'
130
+ console.log(chalk.blue(`Hello ${process.env.HELLO}`))
131
+ ```
132
132
 
133
- ```sh
134
- $ npm install
135
- $ echo "HELLO=World" > .env
133
+ ```sh
134
+ $ npm install
135
+ $ echo "HELLO=World" > .env
136
136
 
137
- $ dotenvx run -- npx tsx index.ts
138
- Hello World
139
- ```
137
+ $ dotenvx run -- npx tsx index.ts
138
+ Hello World
139
+ ```
140
140
 
141
- </details>
142
- * <details><summary>Deno 🦕</summary><br>
141
+ </details>
142
+ <details><summary>Deno 🦕</summary><br>
143
143
 
144
- ```sh
145
- $ echo "HELLO=World" > .env
146
- $ echo "console.log('Hello ' + Deno.env.get('HELLO'))" > index.ts
144
+ ```sh
145
+ $ echo "HELLO=World" > .env
146
+ $ echo "console.log('Hello ' + Deno.env.get('HELLO'))" > index.ts
147
147
 
148
- $ deno run --allow-env index.ts
149
- Hello undefined
148
+ $ deno run --allow-env index.ts
149
+ Hello undefined
150
150
 
151
- $ dotenvx run -- deno run --allow-env index.ts
152
- Hello World
153
- ```
154
-
155
- > [!WARNING]
156
- > Some of you are attempting to use the npm module directly with `deno run`. Don't, because deno currently has incomplete support for these encryption ciphers.
157
- >
158
- > ```
159
- > $ deno run -A npm:@dotenvx/dotenvx encrypt
160
- > Unknown cipher
161
- > ```
162
- >
163
- > Instead, use `dotenvx` as designed, by installing the cli as a binary - via curl, brew, etc.
164
-
165
- </details>
166
- * <details><summary>Bun 🥟</summary><br>
167
-
168
- ```sh
169
- $ echo "HELLO=Test" > .env.test
170
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
151
+ $ dotenvx run -- deno run --allow-env index.ts
152
+ Hello World
153
+ ```
171
154
 
172
- $ bun index.js
173
- Hello undefined
155
+ > [!WARNING]
156
+ > Some of you are attempting to use the npm module directly with `deno run`. Don't, because deno currently has incomplete support for these encryption ciphers.
157
+ >
158
+ > ```
159
+ > $ deno run -A npm:@dotenvx/dotenvx encrypt
160
+ > Unknown cipher
161
+ > ```
162
+ >
163
+ > Instead, use `dotenvx` as designed, by installing the cli as a binary - via curl, brew, etc.
174
164
 
175
- $ dotenvx run -f .env.test -- bun index.js
176
- Hello Test
177
- ```
165
+ </details>
166
+ <details><summary>Bun 🥟</summary><br>
178
167
 
179
- </details>
180
- * <details><summary>Python 🐍</summary><br>
168
+ ```sh
169
+ $ echo "HELLO=Test" > .env.test
170
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
181
171
 
182
- ```sh
183
- $ echo "HELLO=World" > .env
184
- $ echo 'import os;print("Hello " + os.getenv("HELLO", ""))' > index.py
172
+ $ bun index.js
173
+ Hello undefined
185
174
 
186
- $ dotenvx run -- python3 index.py
187
- Hello World
188
- ```
175
+ $ dotenvx run -f .env.test -- bun index.js
176
+ Hello Test
177
+ ```
189
178
 
190
- see [extended python guide](https://dotenvx.com/docs/quickstart)
179
+ </details>
180
+ <details><summary>Python 🐍</summary><br>
191
181
 
192
- </details>
193
- * <details><summary>PHP 🐘</summary><br>
182
+ ```sh
183
+ $ echo "HELLO=World" > .env
184
+ $ echo 'import os;print("Hello " + os.getenv("HELLO", ""))' > index.py
194
185
 
195
- ```sh
196
- $ echo "HELLO=World" > .env
197
- $ echo '<?php echo "Hello {$_SERVER["HELLO"]}\n";' > index.php
186
+ $ dotenvx run -- python3 index.py
187
+ Hello World
188
+ ```
198
189
 
199
- $ dotenvx run -- php index.php
200
- Hello World
201
- ```
190
+ see [extended python guide](https://dotenvx.com/docs/quickstart)
202
191
 
203
- see [extended php guide](https://dotenvx.com/docs/quickstart)
192
+ </details>
193
+ <details><summary>PHP 🐘</summary><br>
204
194
 
205
- </details>
206
- * <details><summary>Ruby 💎</summary><br>
195
+ ```sh
196
+ $ echo "HELLO=World" > .env
197
+ $ echo '<?php echo "Hello {$_SERVER["HELLO"]}\n";' > index.php
207
198
 
208
- ```sh
209
- $ echo "HELLO=World" > .env
210
- $ echo 'puts "Hello #{ENV["HELLO"]}"' > index.rb
199
+ $ dotenvx run -- php index.php
200
+ Hello World
201
+ ```
211
202
 
212
- $ dotenvx run -- ruby index.rb
213
- Hello World
214
- ```
203
+ see [extended php guide](https://dotenvx.com/docs/quickstart)
215
204
 
216
- see [extended ruby guide](https://dotenvx.com/docs/quickstart)
205
+ </details>
206
+ <details><summary>Ruby 💎</summary><br>
217
207
 
218
- </details>
219
- * <details><summary>Go 🐹</summary><br>
208
+ ```sh
209
+ $ echo "HELLO=World" > .env
210
+ $ echo 'puts "Hello #{ENV["HELLO"]}"' > index.rb
220
211
 
221
- ```sh
222
- $ echo "HELLO=World" > .env
223
- $ echo 'package main; import ("fmt"; "os"); func main() { fmt.Printf("Hello %s\n", os.Getenv("HELLO")) }' > main.go
212
+ $ dotenvx run -- ruby index.rb
213
+ Hello World
214
+ ```
224
215
 
225
- $ dotenvx run -- go run main.go
226
- Hello World
227
- ```
216
+ see [extended ruby guide](https://dotenvx.com/docs/quickstart)
228
217
 
229
- see [extended go guide](https://dotenvx.com/docs/quickstart)
218
+ </details>
219
+ <details><summary>Go 🐹</summary><br>
230
220
 
231
- </details>
232
- * <details><summary>Rust 🦀</summary><br>
221
+ ```sh
222
+ $ echo "HELLO=World" > .env
223
+ $ echo 'package main; import ("fmt"; "os"); func main() { fmt.Printf("Hello %s\n", os.Getenv("HELLO")) }' > main.go
233
224
 
234
- ```sh
235
- $ echo "HELLO=World" > .env
236
- $ echo 'fn main() {let hello = std::env::var("HELLO").unwrap_or("".to_string());println!("Hello {hello}");}' > src/main.rs
225
+ $ dotenvx run -- go run main.go
226
+ Hello World
227
+ ```
237
228
 
238
- $ dotenvx run -- cargo run
239
- Hello World
240
- ```
229
+ see [extended go guide](https://dotenvx.com/docs/quickstart)
241
230
 
242
- see [extended rust guide](https://dotenvx.com/docs/quickstart)
231
+ </details>
232
+ <details><summary>Rust 🦀</summary><br>
243
233
 
244
- </details>
245
- * <details><summary>Java ☕️</summary><br>
234
+ ```sh
235
+ $ echo "HELLO=World" > .env
236
+ $ echo 'fn main() {let hello = std::env::var("HELLO").unwrap_or("".to_string());println!("Hello {hello}");}' > src/main.rs
246
237
 
247
- ```sh
248
- $ echo "HELLO=World" > .env
249
- $ echo 'public class Index { public static void main(String[] args) { System.out.println("Hello " + System.getenv("HELLO")); } }' > index.java
238
+ $ dotenvx run -- cargo run
239
+ Hello World
240
+ ```
250
241
 
251
- $ dotenvx run -- java index.java
252
- Hello World
253
- ```
242
+ see [extended rust guide](https://dotenvx.com/docs/quickstart)
254
243
 
255
- </details>
256
- * <details><summary>Clojure 🌿</summary><br>
244
+ </details>
245
+ <details><summary>Java ☕️</summary><br>
257
246
 
258
- ```sh
259
- $ echo "HELLO=World" > .env
260
- $ echo '(println "Hello" (System/getenv "HELLO"))' > index.clj
247
+ ```sh
248
+ $ echo "HELLO=World" > .env
249
+ $ echo 'public class Index { public static void main(String[] args) { System.out.println("Hello " + System.getenv("HELLO")); } }' > index.java
261
250
 
262
- $ dotenvx run -- clojure -M index.clj
263
- Hello World
264
- ```
251
+ $ dotenvx run -- java index.java
252
+ Hello World
253
+ ```
265
254
 
266
- </details>
267
- * <details><summary>Kotlin 📐</summary><br>
255
+ </details>
256
+ <details><summary>Clojure 🌿</summary><br>
268
257
 
269
- ```sh
270
- $ echo "HELLO=World" > .env
271
- $ echo 'fun main() { val hello = System.getenv("HELLO") ?: ""; println("Hello $hello") }' > index.kt
272
- $ kotlinc index.kt -include-runtime -d index.jar
258
+ ```sh
259
+ $ echo "HELLO=World" > .env
260
+ $ echo '(println "Hello" (System/getenv "HELLO"))' > index.clj
273
261
 
274
- $ dotenvx run -- java -jar index.jar
275
- Hello World
276
- ```
262
+ $ dotenvx run -- clojure -M index.clj
263
+ Hello World
264
+ ```
277
265
 
278
- </details>
279
- * <details><summary>.NET 🔵</summary><br>
266
+ </details>
267
+ <details><summary>Kotlin 📐</summary><br>
280
268
 
281
- ```sh
282
- $ dotnet new console -n HelloWorld -o HelloWorld
283
- $ cd HelloWorld
284
- $ echo "HELLO=World" | Out-File -FilePath .env -Encoding utf8
285
- $ echo 'Console.WriteLine($"Hello {Environment.GetEnvironmentVariable("HELLO")}");' > Program.cs
269
+ ```sh
270
+ $ echo "HELLO=World" > .env
271
+ $ echo 'fun main() { val hello = System.getenv("HELLO") ?: ""; println("Hello $hello") }' > index.kt
272
+ $ kotlinc index.kt -include-runtime -d index.jar
286
273
 
287
- $ dotenvx run -- dotnet run
288
- Hello World
289
- ```
274
+ $ dotenvx run -- java -jar index.jar
275
+ Hello World
276
+ ```
290
277
 
291
- </details>
292
- * <details><summary>Bash 🖥️</summary><br>
278
+ </details>
279
+ <details><summary>.NET 🔵</summary><br>
293
280
 
294
- ```sh
295
- $ echo "HELLO=World" > .env
281
+ ```sh
282
+ $ dotnet new console -n HelloWorld -o HelloWorld
283
+ $ cd HelloWorld
284
+ $ echo "HELLO=World" | Out-File -FilePath .env -Encoding utf8
285
+ $ echo 'Console.WriteLine($"Hello {Environment.GetEnvironmentVariable("HELLO")}");' > Program.cs
296
286
 
297
- $ dotenvx run --quiet -- sh -c 'echo Hello $HELLO'
298
- Hello World
299
- ```
287
+ $ dotenvx run -- dotnet run
288
+ Hello World
289
+ ```
300
290
 
301
- </details>
302
- * <details><summary>Fish 🐠</summary><br>
291
+ </details>
292
+ <details><summary>Bash 🖥️</summary><br>
303
293
 
304
- ```sh
305
- $ echo "HELLO=World" > .env
294
+ ```sh
295
+ $ echo "HELLO=World" > .env
306
296
 
307
- $ dotenvx run --quiet -- sh -c 'echo Hello $HELLO'
308
- Hello World
309
- ```
297
+ $ dotenvx run --quiet -- sh -c 'echo Hello $HELLO'
298
+ Hello World
299
+ ```
310
300
 
311
- </details>
312
- * <details><summary>Cron ⏰</summary><br>
301
+ </details>
302
+ <details><summary>Fish 🐠</summary><br>
313
303
 
314
- ```sh
315
- # run every day at 8am
316
- 0 8 * * * dotenvx run -- /path/to/myscript.sh
317
- ```
304
+ ```sh
305
+ $ echo "HELLO=World" > .env
318
306
 
319
- </details>
320
- * <details><summary>Frameworks ▲</summary><br>
307
+ $ dotenvx run --quiet -- sh -c 'echo Hello $HELLO'
308
+ Hello World
309
+ ```
321
310
 
322
- ```sh
323
- $ dotenvx run -- next dev
324
- $ dotenvx run -- npm start
325
- $ dotenvx run -- bin/rails s
326
- $ dotenvx run -- php artisan serve
327
- ```
311
+ </details>
312
+ <details><summary>Cron ⏰</summary><br>
328
313
 
329
- see [framework guides](https://dotenvx.com/docs#frameworks)
314
+ ```sh
315
+ # run every day at 8am
316
+ 0 8 * * * dotenvx run -- /path/to/myscript.sh
317
+ ```
330
318
 
331
- </details>
332
- * <details><summary>Docker 🐳</summary><br>
319
+ </details>
320
+ <details><summary>Frameworks ▲</summary><br>
333
321
 
334
- ```sh
335
- $ docker run -it --rm -v $(pwd):/app dotenv/dotenvx run -- node index.js
336
- ```
322
+ ```sh
323
+ $ dotenvx run -- next dev
324
+ $ dotenvx run -- npm start
325
+ $ dotenvx run -- bin/rails s
326
+ $ dotenvx run -- php artisan serve
327
+ ```
337
328
 
338
- Or in any image:
329
+ see [framework guides](https://dotenvx.com/docs#frameworks)
339
330
 
340
- ```sh
341
- FROM node:latest
342
- RUN echo "HELLO=World" > .env && echo "console.log('Hello ' + process.env.HELLO)" > index.js
343
- RUN curl -fsS https://dotenvx.sh/install.sh | sh
344
- CMD ["dotenvx", "run", "--", "echo", "Hello $HELLO"]
345
- ```
331
+ </details>
332
+ <details><summary>Docker 🐳</summary><br>
346
333
 
347
- see [docker guide](https://dotenvx.com/docs/platforms/docker)
334
+ ```sh
335
+ $ docker run -it --rm -v $(pwd):/app dotenv/dotenvx run -- node index.js
336
+ ```
348
337
 
349
- </details>
350
- * <details><summary>CI/CDs 🐙</summary><br>
338
+ Or in any image:
351
339
 
352
- ```yaml
353
- name: build
354
- on: [push]
355
- jobs:
356
- build:
357
- runs-on: ubuntu-latest
358
- steps:
359
- - uses: actions/checkout@v3
360
- - uses: actions/setup-node@v3
361
- with:
362
- node-version: 16
363
- - run: curl -fsS https://dotenvx.sh/install.sh | sh
364
- - run: dotenvx run -- node build.js
365
- env:
366
- DOTENV_KEY: ${{ secrets.DOTENV_KEY }}
367
- ```
340
+ ```sh
341
+ FROM node:latest
342
+ RUN echo "HELLO=World" > .env && echo "console.log('Hello ' + process.env.HELLO)" > index.js
343
+ RUN curl -fsS https://dotenvx.sh/install.sh | sh
344
+ CMD ["dotenvx", "run", "--", "echo", "Hello $HELLO"]
345
+ ```
368
346
 
369
- see [github actions guide](https://dotenvx.com/docs/cis/github-actions)
347
+ see [docker guide](https://dotenvx.com/docs/platforms/docker)
370
348
 
371
- </details>
372
- * <details><summary>Platforms</summary><br>
349
+ </details>
350
+ <details><summary>CI/CDs 🐙</summary><br>
351
+
352
+ ```yaml
353
+ name: build
354
+ on: [push]
355
+ jobs:
356
+ build:
357
+ runs-on: ubuntu-latest
358
+ steps:
359
+ - uses: actions/checkout@v3
360
+ - uses: actions/setup-node@v3
361
+ with:
362
+ node-version: 16
363
+ - run: curl -fsS https://dotenvx.sh/install.sh | sh
364
+ - run: dotenvx run -- node build.js
365
+ env:
366
+ DOTENV_KEY: ${{ secrets.DOTENV_KEY }}
367
+ ```
373
368
 
374
- ```sh
375
- # heroku
376
- heroku buildpacks:add https://github.com/dotenvx/heroku-buildpack-dotenvx
369
+ see [github actions guide](https://dotenvx.com/docs/cis/github-actions)
377
370
 
378
- # docker
379
- RUN curl -fsS https://dotenvx.sh/install.sh | sh
371
+ </details>
372
+ <details><summary>Platforms</summary><br>
373
+
374
+ ```sh
375
+ # heroku
376
+ heroku buildpacks:add https://github.com/dotenvx/heroku-buildpack-dotenvx
380
377
 
381
- # vercel
382
- npm install @dotenvx/dotenvx --save
383
- ```
378
+ # docker
379
+ RUN curl -fsS https://dotenvx.sh/install.sh | sh
380
+
381
+ # vercel
382
+ npm install @dotenvx/dotenvx --save
383
+ ```
384
+
385
+ see [platform guides](https://dotenvx.com/docs#platforms)
386
+
387
+ </details>
388
+ <details><summary>Process Managers</summary><br>
389
+
390
+ ```js
391
+ // pm2
392
+ "scripts": {
393
+ "start": "dotenvx run -- pm2-runtime start ecosystem.config.js --env production"
394
+ },
395
+ ```
396
+
397
+ see [process manager guides](https://dotenvx.com/docs#process-managers)
398
+
399
+ </details>
400
+ <details><summary>npx</summary><br>
401
+
402
+ ```sh
403
+ # alternatively use npx
404
+ $ npx @dotenvx/dotenvx run -- node index.js
405
+ $ npx @dotenvx/dotenvx run -- next dev
406
+ $ npx @dotenvx/dotenvx run -- npm start
407
+ ```
384
408
 
385
- see [platform guides](https://dotenvx.com/docs#platforms)
409
+ </details>
410
+ <details><summary>npm</summary><br>
386
411
 
387
- </details>
388
- * <details><summary>Process Managers</summary><br>
412
+ ```sh
413
+ $ npm install @dotenvx/dotenvx --save
414
+ ```
389
415
 
390
- ```js
391
- // pm2
416
+ ```json
417
+ {
392
418
  "scripts": {
393
- "start": "dotenvx run -- pm2-runtime start ecosystem.config.js --env production"
419
+ "start": "./node_modules/.bin/dotenvx run -- node index.js"
394
420
  },
395
- ```
396
-
397
- see [process manager guides](https://dotenvx.com/docs#process-managers)
398
-
399
- </details>
400
- * <details><summary>npx</summary><br>
401
-
402
- ```sh
403
- # alternatively use npx
404
- $ npx @dotenvx/dotenvx run -- node index.js
405
- $ npx @dotenvx/dotenvx run -- next dev
406
- $ npx @dotenvx/dotenvx run -- npm start
407
- ```
408
-
409
- </details>
410
- * <details><summary>npm</summary><br>
411
-
412
- ```sh
413
- $ npm install @dotenvx/dotenvx --save
414
- ```
415
-
416
- ```json
417
- {
418
- "scripts": {
419
- "start": "./node_modules/.bin/dotenvx run -- node index.js"
420
- },
421
- "dependencies": {
422
- "@dotenvx/dotenvx": "^0.5.0"
423
- }
421
+ "dependencies": {
422
+ "@dotenvx/dotenvx": "^0.5.0"
424
423
  }
425
- ```
424
+ }
425
+ ```
426
426
 
427
- ```sh
428
- $ npm run start
427
+ ```sh
428
+ $ npm run start
429
429
 
430
- > start
431
- > ./node_modules/.bin/dotenvx run -- node index.js
430
+ > start
431
+ > ./node_modules/.bin/dotenvx run -- node index.js
432
432
 
433
- [dotenvx@1.X.X] injecting env (1) from .env.production
434
- Hello World
435
- ```
436
-
437
- </details>
438
- * <details><summary>asdf</summary><br>
439
-
440
- ```sh
441
- # use dotenvx with asdf
442
- $ asdf plugin add dotenvx
443
- $ asdf install dotenvx latest
444
- ```
445
-
446
- thank you [@jgburet](https://github.com/jgburet/asdf-dotenvx) of Paris 🇫🇷
447
-
448
- </details>
449
- * <details><summary>Git</summary><br>
450
-
451
- ```sh
452
- # use as a git submodule
453
- $ git dotenvx run -- node index.js
454
- $ git dotenvx run -- next dev
455
- $ git dotenvx run -- npm start
456
- ```
457
-
458
- </details>
459
- * <details><summary>Variable Expansion</summary><br>
460
-
461
- Reference and expand variables already on your machine for use in your .env file.
462
-
463
- ```ini
464
- # .env
465
- USERNAME="username"
466
- DATABASE_URL="postgres://${USERNAME}@localhost/my_database"
467
- ```
468
- ```js
469
- // index.js
470
- console.log('DATABASE_URL', process.env.DATABASE_URL)
471
- ```
472
- ```sh
473
- $ dotenvx run --debug -- node index.js
474
- [dotenvx@0.14.1] injecting env (2) from .env
475
- DATABASE_URL postgres://username@localhost/my_database
476
- ```
477
-
478
- </details>
479
- * <details><summary>Command Substitution</summary><br>
480
-
481
- Add the output of a command to one of your variables in your .env file.
482
-
483
- ```ini
484
- # .env
485
- DATABASE_URL="postgres://$(whoami)@localhost/my_database"
486
- ```
487
- ```js
488
- // index.js
489
- console.log('DATABASE_URL', process.env.DATABASE_URL)
490
- ```
491
- ```sh
492
- $ dotenvx run --debug -- node index.js
493
- [dotenvx@0.14.1] injecting env (1) from .env
494
- DATABASE_URL postgres://yourusername@localhost/my_database
495
- ```
496
-
497
- </details>
433
+ [dotenvx@1.X.X] injecting env (1) from .env.production
434
+ Hello World
435
+ ```
436
+
437
+ </details>
438
+ <details><summary>asdf</summary><br>
439
+
440
+ ```sh
441
+ # use dotenvx with asdf
442
+ $ asdf plugin add dotenvx
443
+ $ asdf install dotenvx latest
444
+ ```
445
+
446
+ thank you [@jgburet](https://github.com/jgburet/asdf-dotenvx) of Paris 🇫🇷
447
+
448
+ </details>
449
+ <details><summary>Git</summary><br>
450
+
451
+ ```sh
452
+ # use as a git submodule
453
+ $ git dotenvx run -- node index.js
454
+ $ git dotenvx run -- next dev
455
+ $ git dotenvx run -- npm start
456
+ ```
457
+
458
+ </details>
459
+ <details><summary>Variable Expansion</summary><br>
460
+
461
+ Reference and expand variables already on your machine for use in your .env file.
462
+
463
+ ```ini
464
+ # .env
465
+ USERNAME="username"
466
+ DATABASE_URL="postgres://${USERNAME}@localhost/my_database"
467
+ ```
468
+ ```js
469
+ // index.js
470
+ console.log('DATABASE_URL', process.env.DATABASE_URL)
471
+ ```
472
+ ```sh
473
+ $ dotenvx run --debug -- node index.js
474
+ [dotenvx@0.14.1] injecting env (2) from .env
475
+ DATABASE_URL postgres://username@localhost/my_database
476
+ ```
477
+
478
+ </details>
479
+ <details><summary>Command Substitution</summary><br>
480
+
481
+ Add the output of a command to one of your variables in your .env file.
482
+
483
+ ```ini
484
+ # .env
485
+ DATABASE_URL="postgres://$(whoami)@localhost/my_database"
486
+ ```
487
+ ```js
488
+ // index.js
489
+ console.log('DATABASE_URL', process.env.DATABASE_URL)
490
+ ```
491
+ ```sh
492
+ $ dotenvx run --debug -- node index.js
493
+ [dotenvx@0.14.1] injecting env (1) from .env
494
+ DATABASE_URL postgres://yourusername@localhost/my_database
495
+ ```
496
+
497
+ </details>
498
498
 
499
499
 
500
500
  &nbsp;
@@ -514,2023 +514,2113 @@ Hello production
514
514
 
515
515
  More examples
516
516
 
517
- * <details><summary>multiple `.env` files</summary><br>
517
+ <details><summary>multiple `.env` files</summary><br>
518
518
 
519
- ```sh
520
- $ echo "HELLO=local" > .env.local
519
+ ```sh
520
+ $ echo "HELLO=local" > .env.local
521
521
 
522
- $ echo "HELLO=World" > .env
522
+ $ echo "HELLO=World" > .env
523
523
 
524
- $ dotenvx run -f .env.local -f .env -- node index.js
525
- [dotenvx@1.X.X] injecting env (1) from .env.local,.env
526
- Hello local
527
- ```
524
+ $ dotenvx run -f .env.local -f .env -- node index.js
525
+ [dotenvx@1.X.X] injecting env (1) from .env.local,.env
526
+ Hello local
527
+ ```
528
528
 
529
- Note subsequent files do NOT override pre-existing variables defined in previous files or env. This follows historic principle. For example, above `local` wins – from the first file.
529
+ Note subsequent files do NOT override pre-existing variables defined in previous files or env. This follows historic principle. For example, above `local` wins – from the first file.
530
530
 
531
- </details>
531
+ </details>
532
532
 
533
- * <details><summary>`--overload` flag</summary><br>
533
+ <details><summary>`--overload` flag</summary><br>
534
534
 
535
- ```sh
536
- $ echo "HELLO=local" > .env.local
535
+ ```sh
536
+ $ echo "HELLO=local" > .env.local
537
537
 
538
- $ echo "HELLO=World" > .env
538
+ $ echo "HELLO=World" > .env
539
539
 
540
- $ dotenvx run -f .env.local -f .env --overload -- node index.js
541
- [dotenvx@1.X.X] injecting env (1) from .env.local,.env
542
- Hello World
543
- ```
540
+ $ dotenvx run -f .env.local -f .env --overload -- node index.js
541
+ [dotenvx@1.X.X] injecting env (1) from .env.local,.env
542
+ Hello World
543
+ ```
544
+
545
+ Note that with `--overload` subsequent files DO override pre-existing variables defined in previous files.
546
+ </details>
547
+ <details><summary>`--verbose` flag</summary><br>
548
+
549
+ ```sh
550
+ $ echo "HELLO=production" > .env.production
551
+
552
+ $ dotenvx run -f .env.production --verbose -- node index.js
553
+ [dotenvx][verbose] injecting env from /path/to/.env.production
554
+ [dotenvx][verbose] HELLO set
555
+ [dotenvx@1.X.X] injecting env (1) from .env.production
556
+ Hello production
557
+ ```
558
+
559
+ </details>
560
+ <details><summary>`--debug` flag</summary><br>
561
+
562
+ ```sh
563
+ $ echo "HELLO=production" > .env.production
564
+
565
+ $ dotenvx run -f .env.production --debug -- node index.js
566
+ [dotenvx][debug] configuring options
567
+ [dotenvx][debug] {"envFile":[".env.production"]}
568
+ [dotenvx][verbose] injecting env from /path/to/.env.production
569
+ [dotenvx][debug] reading env from /path/to/.env.production
570
+ [dotenvx][debug] parsing env from /path/to/.env.production
571
+ [dotenvx][debug] {"HELLO":"production"}
572
+ [dotenvx][debug] writing env from /path/to/.env.production
573
+ [dotenvx][verbose] HELLO set
574
+ [dotenvx][debug] HELLO set to production
575
+ [dotenvx@1.X.X] injecting env (1) from .env.production
576
+ Hello production
577
+ ```
578
+
579
+ </details>
580
+ <details><summary>`--quiet` flag</summary><br>
581
+
582
+ Use `--quiet` to suppress all output (except errors).
583
+
584
+ ```sh
585
+ $ echo "HELLO=production" > .env.production
586
+
587
+ $ dotenvx run -f .env.production --quiet -- node index.js
588
+ Hello production
589
+ ```
590
+
591
+ </details>
592
+ <details><summary>`--log-level` flag</summary><br>
593
+
594
+ Set `--log-level` to whatever you wish. For example, to suppress warnings (risky), set log level to `error`:
595
+
596
+ ```sh
597
+ $ echo "HELLO=production" > .env.production
598
+
599
+ $ dotenvx run -f .env.production --log-level=error -- node index.js
600
+ Hello production
601
+ ```
602
+
603
+ Available log levels are `error, warn, info, verbose, debug, silly`
604
+
605
+ </details>
606
+ <details><summary>`--convention` flag</summary><br>
607
+
608
+ Load envs using [Next.js' convention](https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#environment-variable-load-order) or [dotenv-flow convention](https://www.npmjs.com/package/dotenv-flow). Set `--convention` to `nextjs` or `flow`:
609
+
610
+ ```sh
611
+ $ echo "HELLO=development local" > .env.development.local
612
+ $ echo "HELLO=local" > .env.local
613
+ $ echo "HELLO=development" > .env.development
614
+ $ echo "HELLO=env" > .env
615
+
616
+ $ dotenvx run --convention=nextjs -- node index.js
617
+ Hello development local
618
+
619
+ $ dotenvx run --convention=flow -- node index.js
620
+ Hello development local
621
+ ```
622
+
623
+ (more conventions available upon request)
624
+
625
+ </details>
626
+
627
+ &nbsp;
628
+
629
+ ## Encryption
630
+
631
+ > Add encryption to your `.env` files with a single command. Use `dotenvx encrypt`.
632
+
633
+ ```sh
634
+ $ dotenvx encrypt
635
+ ✔ encrypted (.env)
636
+ ```
637
+
638
+ [![encrypted .env](https://github.com/user-attachments/assets/46dfe1a7-a027-4d80-9207-789eccc325dc)](https://dotenvx.com)
639
+
640
+ > A `DOTENV_PUBLIC_KEY` (encryption key) and a `DOTENV_PRIVATE_KEY` (decryption key) are generated using the same public-key cryptography as [Bitcoin](https://en.bitcoin.it/wiki/Secp256k1).
641
+
642
+ More examples
643
+
644
+ <details><summary>`.env`</summary><br>
645
+
646
+ ```sh
647
+ $ echo "HELLO=World" > .env
648
+ $ dotenvx encrypt
649
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
650
+
651
+ $ dotenvx run -- node index.js
652
+ [dotenvx@1.X.X] injecting env (2) from .env
653
+ Hello World
654
+ ```
655
+
656
+ </details>
657
+ <details><summary>`.env.production`</summary><br>
658
+
659
+ ```sh
660
+ $ echo "HELLO=Production" > .env.production
661
+ $ dotenvx encrypt -f .env.production
662
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
663
+
664
+ $ DOTENV_PRIVATE_KEY_PRODUCTION="<.env.production private key>" dotenvx run -- node index.js
665
+ [dotenvx@1.X.X] injecting env (2) from .env.production
666
+ Hello Production
667
+ ```
668
+
669
+ Note the `DOTENV_PRIVATE_KEY_PRODUCTION` ends with `_PRODUCTION`. This instructs `dotenvx run` to load the `.env.production` file.
670
+
671
+ </details>
672
+ <details><summary>`.env.ci`</summary><br>
673
+
674
+ ```sh
675
+ $ echo "HELLO=Ci" > .env.ci
676
+ $ dotenvx encrypt -f .env.ci
677
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
678
+
679
+ $ DOTENV_PRIVATE_KEY_CI="<.env.ci private key>" dotenvx run -- node index.js
680
+ [dotenvx@1.X.X] injecting env (2) from .env.ci
681
+ Hello Ci
682
+ ```
683
+
684
+ Note the `DOTENV_PRIVATE_KEY_CI` ends with `_CI`. This instructs `dotenvx run` to load the `.env.ci` file. See the pattern?
685
+
686
+ </details>
687
+ <details><summary>combine multiple encrypted .env files</summary><br>
688
+
689
+ ```sh
690
+ $ dotenvx set HELLO World -f .env
691
+ $ dotenvx set HELLO Production -f .env.production
692
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
693
+
694
+ $ DOTENV_PRIVATE_KEY="<.env private key>" DOTENV_PRIVATE_KEY_PRODUCTION="<.env.production private key>" dotenvx run -- node index.js
695
+ [dotenvx@1.X.X] injecting env (3) from .env, .env.production
696
+ Hello World
697
+ ```
698
+
699
+ Note the `DOTENV_PRIVATE_KEY` instructs `dotenvx run` to load the `.env` file and the `DOTENV_PRIVATE_KEY_PRODUCTION` instructs it to load the `.env.production` file. See the pattern?
700
+
701
+ </details>
702
+ <details><summary>combine multiple encrypted .env files for monorepo</summary><br>
703
+
704
+ ```sh
705
+ $ mkdir app1
706
+ $ mkdir app2
707
+ $ dotenvx set HELLO app1 -f app1/.env.ci
708
+ $ dotenvx set HELLO app2 -f app2/.env.ci
709
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
710
+
711
+ $ DOTENV_PRIVATE_KEY_CI="<app1/privat ci key>,<app2/private ci key>" dotenvx run -f app1/.env.ci -f app2/.env.ci -- node index.js
712
+ [dotenvx@1.X.X] injecting env (2) from app1/.env.ci,app2/.env.ci
713
+ Hello app1
714
+
715
+ $ DOTENV_PRIVATE_KEY_CI="<app1/privat ci key>,<app2/private ci key>" dotenvx run -f app1/.env.ci -f app2/.env.ci --overload -- node index.js
716
+ [dotenvx@1.X.X] injecting env (2) from app1/.env.ci,app2/.env.ci
717
+ Hello app2
718
+ ```
719
+
720
+ Note the `DOTENV_PRIVATE_KEY_CI` (and any `DOTENV_PRIVATE_KEY*`) can take multiple private keys by simply comma separating them.
721
+
722
+ </details>
723
+ <details><summary>`--stdout`</summary><br>
724
+
725
+ ```sh
726
+ $ echo "HELLO=World" > .env
727
+ $ dotenvx encrypt --stdout
728
+ $ dotenvx encrypt --stdout > .env.encrypted
729
+ ```
730
+
731
+ </details>
732
+
733
+ <details><summary>other curves</summary><br>
734
+
735
+ > `secp256k1` is a well-known and battle tested curve, in use with Bitcoin and other cryptocurrencies, but we are open to adding support for more curves.
736
+ >
737
+ > If your organization's compliance department requires [NIST approved curves](https://csrc.nist.gov/projects/elliptic-curve-cryptography) or other curves like `curve25519`, please reach out at [security@dotenvx.com](mailto:security@dotenvx.com).
738
+
739
+ </details>
740
+
741
+ &nbsp;
742
+
743
+ ## Advanced
744
+
745
+ > Become a `dotenvx` power user.
746
+ >
747
+
748
+ ### CLI 📟
749
+
750
+ Advanced CLI commands.
751
+
752
+ <details><summary>`run` - Variable Expansion</summary><br>
753
+
754
+ Reference and expand variables already on your machine for use in your .env file.
755
+
756
+ ```ini
757
+ # .env
758
+ USERNAME="username"
759
+ DATABASE_URL="postgres://${USERNAME}@localhost/my_database"
760
+ ```
761
+ ```js
762
+ // index.js
763
+ console.log('DATABASE_URL', process.env.DATABASE_URL)
764
+ ```
765
+ ```sh
766
+ $ dotenvx run --debug -- node index.js
767
+ [dotenvx@1.X.X] injecting env (2) from .env
768
+ DATABASE_URL postgres://username@localhost/my_database
769
+ ```
770
+
771
+ </details>
772
+ <details><summary>`run` - Default Values</summary><br>
773
+
774
+ Use default values when environment variables are unset or empty.
775
+
776
+ ```ini
777
+ # .env
778
+ # Default value syntax: use value if set, otherwise use default
779
+ DATABASE_HOST=${DB_HOST:-localhost}
780
+ DATABASE_PORT=${DB_PORT:-5432}
781
+
782
+ # Alternative syntax (no colon): use value if set, otherwise use default
783
+ API_URL=${API_BASE_URL-https://api.example.com}
784
+ ```
785
+ ```js
786
+ // index.js
787
+ console.log('DATABASE_HOST', process.env.DATABASE_HOST)
788
+ console.log('DATABASE_PORT', process.env.DATABASE_PORT)
789
+ console.log('API_URL', process.env.API_URL)
790
+ ```
791
+ ```sh
792
+ $ dotenvx run --debug -- node index.js
793
+ [dotenvx@1.X.X] injecting env (3) from .env
794
+ DATABASE_HOST localhost
795
+ DATABASE_PORT 5432
796
+ API_URL https://api.example.com
797
+ ```
798
+
799
+ </details>
800
+ <details><summary>`run` - Alternate Values</summary><br>
801
+
802
+ Use alternate values when environment variables are set and non-empty.
803
+
804
+ ```ini
805
+ # .env
806
+ NODE_ENV=production
807
+
808
+ # Alternate value syntax: use alternate if set and non-empty, otherwise empty
809
+ DEBUG_MODE=${NODE_ENV:+false}
810
+ LOG_LEVEL=${NODE_ENV:+error}
811
+
812
+ # Alternative syntax (no colon): use alternate if set, otherwise empty
813
+ CACHE_ENABLED=${NODE_ENV+true}
814
+ ```
815
+ ```js
816
+ // index.js
817
+ console.log('NODE_ENV', process.env.NODE_ENV)
818
+ console.log('DEBUG_MODE', process.env.DEBUG_MODE)
819
+ console.log('LOG_LEVEL', process.env.LOG_LEVEL)
820
+ console.log('CACHE_ENABLED', process.env.CACHE_ENABLED)
821
+ ```
822
+ ```sh
823
+ $ dotenvx run --debug -- node index.js
824
+ [dotenvx@1.X.X] injecting env (4) from .env
825
+ NODE_ENV production
826
+ DEBUG_MODE false
827
+ LOG_LEVEL error
828
+ CACHE_ENABLED true
829
+ ```
830
+
831
+ </details>
832
+ <details><summary>`run` - Interpolation Syntax Summary (Variable Expansion, Default/Alternate Values)</summary><br>
833
+
834
+ Complete reference for variable interpolation patterns supported by dotenvx:
835
+
836
+ ```ini
837
+ # .env
838
+ DEFINED_VAR=hello
839
+ EMPTY_VAR=
840
+ # UNDEFINED_VAR is not set
841
+
842
+ # Default value syntax - use variable if set/non-empty, otherwise use default
843
+ TEST1=${DEFINED_VAR:-fallback} # Result: "hello"
844
+ TEST2=${EMPTY_VAR:-fallback} # Result: "fallback"
845
+ TEST3=${UNDEFINED_VAR:-fallback} # Result: "fallback"
846
+
847
+ # Default value syntax (no colon) - use variable if set, otherwise use default
848
+ TEST4=${DEFINED_VAR-fallback} # Result: "hello"
849
+ TEST5=${EMPTY_VAR-fallback} # Result: "" (empty, but set)
850
+ TEST6=${UNDEFINED_VAR-fallback} # Result: "fallback"
851
+
852
+ # Alternate value syntax - use alternate if variable is set/non-empty, otherwise empty
853
+ TEST7=${DEFINED_VAR:+alternate} # Result: "alternate"
854
+ TEST8=${EMPTY_VAR:+alternate} # Result: "" (empty)
855
+ TEST9=${UNDEFINED_VAR:+alternate} # Result: "" (empty)
856
+
857
+ # Alternate value syntax (no colon) - use alternate if variable is set, otherwise empty
858
+ TEST10=${DEFINED_VAR+alternate} # Result: "alternate"
859
+ TEST11=${EMPTY_VAR+alternate} # Result: "alternate" (empty but set)
860
+ TEST12=${UNDEFINED_VAR+alternate} # Result: "" (empty)
861
+ ```
862
+
863
+ **Key differences:**
864
+ - `:-` vs `-`: The colon makes empty values trigger the fallback
865
+ - `:+` vs `+`: The colon makes empty values not trigger the alternate
866
+ - Default syntax (`-`): Use variable value or fallback
867
+ - Alternate syntax (`+`): Use alternate value or empty string
868
+
869
+ </details>
870
+ <details><summary>`run` - Command Substitution</summary><br>
871
+
872
+ Add the output of a command to one of your variables in your .env file.
873
+
874
+ ```ini
875
+ # .env
876
+ DATABASE_URL="postgres://$(whoami)@localhost/my_database"
877
+ ```
878
+ ```js
879
+ // index.js
880
+ console.log('DATABASE_URL', process.env.DATABASE_URL)
881
+ ```
882
+ ```sh
883
+ $ dotenvx run --debug -- node index.js
884
+ [dotenvx@1.X.X] injecting env (1) from .env
885
+ DATABASE_URL postgres://yourusername@localhost/my_database
886
+ ```
887
+
888
+ </details>
889
+ <details><summary>`run` - Shell Expansion</summary><br>
890
+
891
+ Prevent your shell from expanding inline `$VARIABLES` before dotenvx has a chance to inject it. Use a subshell.
892
+
893
+ ```sh
894
+ $ dotenvx run --env="HELLO=World" -- sh -c 'echo Hello $HELLO'
895
+ Hello World
896
+ ```
897
+
898
+ </details>
899
+ <details><summary>`run` - Multiline</summary><br>
900
+
901
+ Dotenvx supports multiline values. This is particularly useful in conjunction with Docker - which [does not support multiline values](https://stackoverflow.com/questions/50299617/set-multiline-environment-variable-with-dockerfile/79578348#79578348).
902
+
903
+ ```ini
904
+ # .env
905
+ MULTILINE_PEM="-----BEGIN PUBLIC KEY-----
906
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u
907
+ LgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/
908
+ bTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/
909
+ kKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V
910
+ u4QuUoobAgMBAAE=
911
+ -----END PUBLIC KEY-----"
912
+ ```
913
+
914
+ ```js
915
+ // index.js
916
+ console.log('MULTILINE_PEM', process.env.MULTILINE_PEM)
917
+ ```
918
+
919
+ ```sh
920
+ $ dotenvx run -- node index.js
921
+ MULTILINE_PEM -----BEGIN PUBLIC KEY-----
922
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u
923
+ LgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/
924
+ bTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/
925
+ kKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V
926
+ u4QuUoobAgMBAAE=
927
+ -----END PUBLIC KEY-----
928
+ ```
929
+
930
+ </details>
931
+ <details><summary>`run` - Contextual Help</summary><br>
932
+
933
+ Unlike other dotenv libraries, dotenvx attempts to unblock you with contextual help.
934
+
935
+ For example, when missing a custom .env file:
936
+
937
+ ```sh
938
+ $ dotenvx run -f .env.missing -- echo $HELLO
939
+ [MISSING_ENV_FILE] missing .env.missing file (/Users/scottmotte/Code/dotenvx/playground/apr-16/.env.missing)
940
+ [MISSING_ENV_FILE] https://github.com/dotenvx/dotenvx/issues/484 and re-run [dotenvx run -- echo]
941
+ ```
942
+
943
+ or when missing a KEY:
944
+
945
+ ```sh
946
+ $ echo "HELLO=World" > .env
947
+ $ dotenvx get GOODBYE
948
+ [MISSING_KEY] missing GOODBYE key
949
+ ```
950
+
951
+ </details>
952
+ <details><summary>`run` - multiple `-f` flags</summary><br>
953
+
954
+ Compose multiple `.env` files for environment variables loading, as you need.
955
+
956
+ ```sh
957
+ $ echo "HELLO=local" > .env.local
958
+ $ echo "HELLO=World" > .env
959
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
960
+
961
+ $ dotenvx run -f .env.local -f .env -- node index.js
962
+ [dotenvx@1.X.X] injecting env (1) from .env.local, .env
963
+ Hello local
964
+ ```
965
+
966
+ Note subsequent files do NOT override pre-existing variables defined in previous files or env. This follows historic principle. For example, above `local` wins – from the first file.
967
+
968
+ </details>
969
+ <details><summary>`run --env HELLO=String`</summary><br>
970
+
971
+ Set environment variables as a simple `KEY=value` string pair.
972
+
973
+ ```sh
974
+ $ echo "HELLO=World" > .env
975
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
976
+
977
+ $ dotenvx run --env HELLO=String -f .env -- node index.js
978
+ [dotenvx@1.X.X] injecting env (1) from .env, and --env flag
979
+ Hello String
980
+ ```
981
+
982
+ </details>
983
+ <details><summary>`run --overload`</summary><br>
984
+
985
+ Override existing env variables. These can be variables already on your machine or variables loaded as files consecutively. The last variable seen will 'win'.
986
+
987
+ ```sh
988
+ $ echo "HELLO=local" > .env.local
989
+ $ echo "HELLO=World" > .env
990
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
991
+
992
+ $ dotenvx run -f .env.local -f .env --overload -- node index.js
993
+ [dotenvx@1.X.X] injecting env (1) from .env.local, .env
994
+ Hello World
995
+ ```
996
+
997
+ Note that with `--overload` subsequent files DO override pre-existing variables defined in previous files.
998
+
999
+ </details>
1000
+ <details><summary>`run` - Environment Variable Precedence (Container/Cloud Deployments)</summary><br>
1001
+
1002
+ When deploying applications in containers or cloud environments, you often need to override specific environment variables at runtime without modifying committed `.env` files. By default, dotenvx follows the historic dotenv principle: **environment variables already present take precedence over `.env` files**.
1003
+
1004
+ ```sh
1005
+ # .env.prod contains: MODEL_REGISTRY=registry.company.com/models/v1
1006
+ $ echo "MODEL_REGISTRY=registry.company.com/models/v1" > .env.prod
1007
+ $ echo "console.log('MODEL_REGISTRY:', process.env.MODEL_REGISTRY)" > app.js
1008
+
1009
+ # Without environment variable set - uses .env.prod value
1010
+ $ dotenvx run -f .env.prod -- node app.js
1011
+ MODEL_REGISTRY: registry.company.com/models/v1
1012
+
1013
+ # With environment variable set (e.g., via Azure Container Service) - environment variable takes precedence
1014
+ $ MODEL_REGISTRY=registry.azure.com/models/v2 dotenvx run -f .env.prod -- node app.js
1015
+ MODEL_REGISTRY: registry.azure.com/models/v2
1016
+
1017
+ # To force .env.prod to override environment variables, use --overload
1018
+ $ MODEL_REGISTRY=registry.azure.com/models/v2 dotenvx run -f .env.prod --overload -- node app.js
1019
+ MODEL_REGISTRY: registry.company.com/models/v1
1020
+ ```
1021
+
1022
+ **For container deployments:** Set environment variables through your cloud provider's UI/configuration (Azure Container Service, AWS ECS, etc.) to override specific values from committed `.env` files without rebuilding your application.
1023
+
1024
+ </details>
1025
+ <details><summary>`DOTENV_PRIVATE_KEY=key run`</summary><br>
1026
+
1027
+ Decrypt your encrypted `.env` by setting `DOTENV_PRIVATE_KEY` before `dotenvx run`.
1028
+
1029
+ ```sh
1030
+ $ touch .env
1031
+ $ dotenvx set HELLO encrypted
1032
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1033
+
1034
+ # check your .env.keys files for your privateKey
1035
+ $ DOTENV_PRIVATE_KEY="122...0b8" dotenvx run -- node index.js
1036
+ [dotenvx@1.X.X] injecting env (2) from .env
1037
+ Hello encrypted
1038
+ ```
1039
+
1040
+ </details>
1041
+ <details><summary>`DOTENV_PRIVATE_KEY_PRODUCTION=key run`</summary><br>
1042
+
1043
+ Decrypt your encrypted `.env.production` by setting `DOTENV_PRIVATE_KEY_PRODUCTION` before `dotenvx run`. Alternatively, this can be already set on your server or cloud provider.
1044
+
1045
+ ```sh
1046
+ $ touch .env.production
1047
+ $ dotenvx set HELLO "production encrypted" -f .env.production
1048
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1049
+
1050
+ # check .env.keys for your privateKey
1051
+ $ DOTENV_PRIVATE_KEY_PRODUCTION="122...0b8" dotenvx run -- node index.js
1052
+ [dotenvx@1.X.X] injecting env (2) from .env.production
1053
+ Hello production encrypted
1054
+ ```
1055
+
1056
+ Note the `DOTENV_PRIVATE_KEY_PRODUCTION` ends with `_PRODUCTION`. This instructs dotenvx run to load the `.env.production` file.
1057
+
1058
+ </details>
1059
+ <details><summary>`DOTENV_PRIVATE_KEY_CI=key dotenvx run`</summary><br>
1060
+
1061
+ Decrypt your encrypted `.env.ci` by setting `DOTENV_PRIVATE_KEY_CI` before `dotenvx run`. Alternatively, this can be already set on your server or cloud provider.
1062
+
1063
+ ```sh
1064
+ $ touch .env.ci
1065
+ $ dotenvx set HELLO "ci encrypted" -f .env.ci
1066
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
544
1067
 
545
- Note that with `--overload` subsequent files DO override pre-existing variables defined in previous files.
1068
+ # check .env.keys for your privateKey
1069
+ $ DOTENV_PRIVATE_KEY_CI="122...0b8" dotenvx run -- node index.js
1070
+ [dotenvx@1.X.X] injecting env (2) from .env.ci
1071
+ Hello ci encrypted
1072
+ ```
1073
+
1074
+ Note the `DOTENV_PRIVATE_KEY_CI` ends with `_CI`. This instructs dotenvx run to load the `.env.ci` file. See the pattern?
1075
+
1076
+ </details>
1077
+ <details><summary>`DOTENV_PRIVATE_KEY=key DOTENV_PRIVATE_KEY_PRODUCTION=key run` - Combine Multiple</summary><br>
546
1078
 
547
- * <details><summary>`--verbose` flag</summary><br>
1079
+ Decrypt your encrypted `.env` and `.env.production` files by setting `DOTENV_PRIVATE_KEY` and `DOTENV_PRIVATE_KEY_PRODUCTION` before `dotenvx run`.
548
1080
 
549
- ```sh
550
- $ echo "HELLO=production" > .env.production
1081
+ ```sh
1082
+ $ touch .env
1083
+ $ touch .env.production
1084
+ $ dotenvx set HELLO encrypted
1085
+ $ dotenvx set HELLO "production encrypted" -f .env.production
1086
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
551
1087
 
552
- $ dotenvx run -f .env.production --verbose -- node index.js
553
- [dotenvx][verbose] injecting env from /path/to/.env.production
554
- [dotenvx][verbose] HELLO set
555
- [dotenvx@1.X.X] injecting env (1) from .env.production
556
- Hello production
557
- ```
1088
+ # check .env.keys for your privateKeys
1089
+ $ DOTENV_PRIVATE_KEY="122...0b8" DOTENV_PRIVATE_KEY_PRODUCTION="122...0b8" dotenvx run -- node index.js
1090
+ [dotenvx@1.X.X] injecting env (3) from .env, .env.production
1091
+ Hello encrypted
1092
+
1093
+ $ DOTENV_PRIVATE_KEY_PRODUCTION="122...0b8" DOTENV_PRIVATE_KEY="122...0b8" dotenvx run -- node index.js
1094
+ [dotenvx@1.X.X] injecting env (3) from .env.production, .env
1095
+ Hello production encrypted
1096
+ ```
558
1097
 
559
- * <details><summary>`--debug` flag</summary><br>
1098
+ Compose any encrypted files you want this way. As long as a `DOTENV_PRIVATE_KEY_${environment}` is set, the values from `.env.${environment}` will be decrypted at runtime.
1099
+
1100
+ </details>
1101
+ <details><summary>`run --verbose`</summary><br>
1102
+
1103
+ Set log level to `verbose`. ([log levels](https://docs.npmjs.com/cli/v8/using-npm/logging#setting-log-levels))
1104
+
1105
+ ```sh
1106
+ $ echo "HELLO=production" > .env.production
1107
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
560
1108
 
561
- ```sh
562
- $ echo "HELLO=production" > .env.production
1109
+ $ dotenvx run -f .env.production --verbose -- node index.js
1110
+ loading env from .env.production (/path/to/.env.production)
1111
+ HELLO set
1112
+ [dotenvx@1.X.X] injecting env (1) from .env.production
1113
+ Hello production
1114
+ ```
1115
+
1116
+ </details>
1117
+ <details><summary>`run --debug`</summary><br>
1118
+
1119
+ Set log level to `debug`. ([log levels](https://docs.npmjs.com/cli/v8/using-npm/logging#setting-log-levels))
1120
+
1121
+ ```sh
1122
+ $ echo "HELLO=production" > .env.production
1123
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1124
+
1125
+ $ dotenvx run -f .env.production --debug -- node index.js
1126
+ process command [node index.js]
1127
+ options: {"env":[],"envFile":[".env.production"]}
1128
+ loading env from .env.production (/path/to/.env.production)
1129
+ {"HELLO":"production"}
1130
+ HELLO set
1131
+ HELLO set to production
1132
+ [dotenvx@1.X.X] injecting env (1) from .env.production
1133
+ executing process command [node index.js]
1134
+ expanding process command to [/opt/homebrew/bin/node index.js]
1135
+ Hello production
1136
+ ```
563
1137
 
564
- $ dotenvx run -f .env.production --debug -- node index.js
565
- [dotenvx][debug] configuring options
566
- [dotenvx][debug] {"envFile":[".env.production"]}
567
- [dotenvx][verbose] injecting env from /path/to/.env.production
568
- [dotenvx][debug] reading env from /path/to/.env.production
569
- [dotenvx][debug] parsing env from /path/to/.env.production
570
- [dotenvx][debug] {"HELLO":"production"}
571
- [dotenvx][debug] writing env from /path/to/.env.production
572
- [dotenvx][verbose] HELLO set
573
- [dotenvx][debug] HELLO set to production
574
- [dotenvx@1.X.X] injecting env (1) from .env.production
575
- Hello production
576
- ```
1138
+ </details>
1139
+ <details><summary>`run --quiet`</summary><br>
577
1140
 
578
- </details>
579
- * <details><summary>`--quiet` flag</summary><br>
1141
+ Use `--quiet` to suppress all output (except errors). ([log levels](https://docs.npmjs.com/cli/v8/using-npm/logging#setting-log-levels))
580
1142
 
581
- Use `--quiet` to suppress all output (except errors).
1143
+ ```sh
1144
+ $ echo "HELLO=production" > .env.production
1145
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
582
1146
 
583
- ```sh
584
- $ echo "HELLO=production" > .env.production
1147
+ $ dotenvx run -f .env.production --quiet -- node index.js
1148
+ Hello production
1149
+ ```
585
1150
 
586
- $ dotenvx run -f .env.production --quiet -- node index.js
587
- Hello production
588
- ```
1151
+ </details>
1152
+ <details><summary>`run --log-level`</summary><br>
589
1153
 
590
- </details>
591
- * <details><summary>`--log-level` flag</summary><br>
1154
+ Set `--log-level` to whatever you wish. For example, to suppress warnings (risky), set log level to `error`:
592
1155
 
593
- Set `--log-level` to whatever you wish. For example, to suppress warnings (risky), set log level to `error`:
1156
+ ```sh
1157
+ $ echo "HELLO=production" > .env.production
1158
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
594
1159
 
595
- ```sh
596
- $ echo "HELLO=production" > .env.production
1160
+ $ dotenvx run -f .env.production --log-level=error -- node index.js
1161
+ Hello production
1162
+ ```
597
1163
 
598
- $ dotenvx run -f .env.production --log-level=error -- node index.js
599
- Hello production
600
- ```
1164
+ Available log levels are `error, warn, info, verbose, debug, silly` ([source](https://docs.npmjs.com/cli/v8/using-npm/logging#setting-log-levels))
601
1165
 
602
- Available log levels are `error, warn, info, verbose, debug, silly`
1166
+ </details>
1167
+ <details><summary>`run --strict`</summary><br>
603
1168
 
604
- </details>
605
- * <details><summary>`--convention` flag</summary><br>
1169
+ Exit with code `1` if any errors are encountered - like a missing .env file or decryption failure.
606
1170
 
607
- Load envs using [Next.js' convention](https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#environment-variable-load-order) or [dotenv-flow convention](https://www.npmjs.com/package/dotenv-flow). Set `--convention` to `nextjs` or `flow`:
1171
+ ```sh
1172
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
608
1173
 
609
- ```sh
610
- $ echo "HELLO=development local" > .env.development.local
611
- $ echo "HELLO=local" > .env.local
612
- $ echo "HELLO=development" > .env.development
613
- $ echo "HELLO=env" > .env
1174
+ $ dotenvx run -f .env.missing --strict -- node index.js
1175
+ [MISSING_ENV_FILE] missing .env.missing file (/path/to/.env.missing)
1176
+ [MISSING_ENV_FILE] ? add one with [echo "HELLO=World" > .env.missing]
1177
+ ```
614
1178
 
615
- $ dotenvx run --convention=nextjs -- node index.js
616
- Hello development local
1179
+ This can be useful in `ci` scripts where you want to fail the ci if your `.env` file could not be decrypted at runtime.
617
1180
 
618
- $ dotenvx run --convention=flow -- node index.js
619
- Hello development local
620
- ```
1181
+ </details>
1182
+ <details><summary>`run --ignore`</summary><br>
621
1183
 
622
- (more conventions available upon request)
1184
+ Ignore errors like `MISSING_ENV_FILE`.
623
1185
 
624
- </details>
1186
+ ```sh
1187
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
625
1188
 
626
- &nbsp;
1189
+ $ dotenvx run -f .env.missing --ignore=MISSING_ENV_FILE -- node index.js
1190
+ ...
1191
+ ```
627
1192
 
628
- ## Encryption
1193
+ </details>
1194
+ <details><summary>`run --convention=nextjs`</summary><br>
629
1195
 
630
- > Add encryption to your `.env` files with a single command. Use `dotenvx encrypt`.
1196
+ Load envs using [Next.js' convention](https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#environment-variable-load-order). Set `--convention` to `nextjs`:
631
1197
 
632
1198
  ```sh
633
- $ dotenvx encrypt
634
- encrypted (.env)
635
- ```
636
-
637
- [![encrypted .env](https://github.com/user-attachments/assets/46dfe1a7-a027-4d80-9207-789eccc325dc)](https://dotenvx.com)
638
-
639
- > A `DOTENV_PUBLIC_KEY` (encryption key) and a `DOTENV_PRIVATE_KEY` (decryption key) are generated using the same public-key cryptography as [Bitcoin](https://en.bitcoin.it/wiki/Secp256k1).
1199
+ $ echo "HELLO=development local" > .env.development.local
1200
+ $ echo "HELLO=local" > .env.local
1201
+ $ echo "HELLO=development" > .env.development
1202
+ $ echo "HELLO=env" > .env
1203
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
640
1204
 
641
- More examples
1205
+ $ dotenvx run --convention=nextjs -- node index.js
1206
+ [dotenvx@1.X.X] injecting env (1) from .env.development.local, .env.local, .env.development, .env
1207
+ Hello development local
1208
+ ```
642
1209
 
643
- * <details><summary>`.env`</summary><br>
1210
+ (more conventions available upon request)
644
1211
 
645
- ```sh
646
- $ echo "HELLO=World" > .env
647
- $ dotenvx encrypt
648
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1212
+ </details>
1213
+ <details><summary>`run --convention=flow`</summary><br>
649
1214
 
650
- $ dotenvx run -- node index.js
651
- [dotenvx@1.X.X] injecting env (2) from .env
652
- Hello World
653
- ```
1215
+ Load envs using [dotenv-flow's convention](https://www.npmjs.com/package/dotenv-flow). Set `--convention` to `flow`:
654
1216
 
655
- </details>
656
- * <details><summary>`.env.production`</summary><br>
1217
+ ```sh
1218
+ $ echo "HELLO=development local" > .env.development.local
1219
+ $ echo "HELLO=development" > .env.development
1220
+ $ echo "HELLO=local" > .env.local
1221
+ $ echo "HELLO=env" > .env
1222
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
657
1223
 
658
- ```sh
659
- $ echo "HELLO=Production" > .env.production
660
- $ dotenvx encrypt -f .env.production
661
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1224
+ $ NODE_ENV=development dotenvx run --convention=flow -- node index.js
1225
+ [dotenvx@1.X.X] injecting env (1) from .env.development.local, .env.development, .env.local, .env
1226
+ Hello development local
1227
+ ```
662
1228
 
663
- $ DOTENV_PRIVATE_KEY_PRODUCTION="<.env.production private key>" dotenvx run -- node index.js
664
- [dotenvx@1.X.X] injecting env (2) from .env.production
665
- Hello Production
666
- ```
1229
+ Further, we recommend using `DOTENV_ENV` over `NODE_ENV`– as `dotenvx` works everywhere, not just node.
667
1230
 
668
- Note the `DOTENV_PRIVATE_KEY_PRODUCTION` ends with `_PRODUCTION`. This instructs `dotenvx run` to load the `.env.production` file.
1231
+ ```sh
1232
+ $ DOTENV_ENV=development dotenvx run --convention=flow -- node index.js
1233
+ [dotenvx@1.X.X] injecting env (1) from .env.development.local, .env.development, .env.local, .env
1234
+ Hello development local
1235
+ ```
669
1236
 
670
- </details>
671
- * <details><summary>`.env.ci`</summary><br>
1237
+ </details>
1238
+ <details><summary>`run -fk`</summary><br>
672
1239
 
673
- ```sh
674
- $ echo "HELLO=Ci" > .env.ci
675
- $ dotenvx encrypt -f .env.ci
676
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1240
+ Specify path to `.env.keys`. This is useful with monorepos.
677
1241
 
678
- $ DOTENV_PRIVATE_KEY_CI="<.env.ci private key>" dotenvx run -- node index.js
679
- [dotenvx@1.X.X] injecting env (2) from .env.ci
680
- Hello Ci
681
- ```
1242
+ ```sh
1243
+ $ mkdir -p apps/app1
1244
+ $ touch apps/app1/.env
1245
+ $ dotenvx set HELLO world -fk .env.keys -f apps/app1/.env
682
1246
 
683
- Note the `DOTENV_PRIVATE_KEY_CI` ends with `_CI`. This instructs `dotenvx run` to load the `.env.ci` file. See the pattern?
1247
+ $ dotenvx run -fk .env.keys -f apps/app1/.env -- yourcommand
1248
+ ```
684
1249
 
685
- </details>
686
- * <details><summary>combine multiple encrypted .env files</summary><br>
1250
+ </details>
1251
+ <details><summary>`get KEY`</summary><br>
687
1252
 
688
- ```sh
689
- $ dotenvx set HELLO World -f .env
690
- $ dotenvx set HELLO Production -f .env.production
691
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1253
+ Return a single environment variable's value.
692
1254
 
693
- $ DOTENV_PRIVATE_KEY="<.env private key>" DOTENV_PRIVATE_KEY_PRODUCTION="<.env.production private key>" dotenvx run -- node index.js
694
- [dotenvx@1.X.X] injecting env (3) from .env, .env.production
695
- Hello World
696
- ```
1255
+ ```sh
1256
+ $ echo "HELLO=World" > .env
697
1257
 
698
- Note the `DOTENV_PRIVATE_KEY` instructs `dotenvx run` to load the `.env` file and the `DOTENV_PRIVATE_KEY_PRODUCTION` instructs it to load the `.env.production` file. See the pattern?
1258
+ $ dotenvx get HELLO
1259
+ World
1260
+ ```
699
1261
 
700
- </details>
701
- * <details><summary>combine multiple encrypted .env files for monorepo</summary><br>
1262
+ </details>
1263
+ <details><summary>`get KEY -f`</summary><br>
702
1264
 
703
- ```sh
704
- $ mkdir app1
705
- $ mkdir app2
706
- $ dotenvx set HELLO app1 -f app1/.env.ci
707
- $ dotenvx set HELLO app2 -f app2/.env.ci
708
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1265
+ Return a single environment variable's value from a specific `.env` file.
709
1266
 
710
- $ DOTENV_PRIVATE_KEY_CI="<app1/privat ci key>,<app2/private ci key>" dotenvx run -f app1/.env.ci -f app2/.env.ci -- node index.js
711
- [dotenvx@1.X.X] injecting env (2) from app1/.env.ci,app2/.env.ci
712
- Hello app1
1267
+ ```sh
1268
+ $ echo "HELLO=World" > .env
1269
+ $ echo "HELLO=production" > .env.production
713
1270
 
714
- $ DOTENV_PRIVATE_KEY_CI="<app1/privat ci key>,<app2/private ci key>" dotenvx run -f app1/.env.ci -f app2/.env.ci --overload -- node index.js
715
- [dotenvx@1.X.X] injecting env (2) from app1/.env.ci,app2/.env.ci
716
- Hello app2
717
- ```
1271
+ $ dotenvx get HELLO -f .env.production
1272
+ production
1273
+ ```
718
1274
 
719
- Note the `DOTENV_PRIVATE_KEY_CI` (and any `DOTENV_PRIVATE_KEY*`) can take multiple private keys by simply comma separating them.
1275
+ </details>
1276
+ <details><summary>`get KEY -fk`</summary><br>
720
1277
 
721
- </details>
722
- * <details><summary>`--stdout`</summary><br>
1278
+ Specify path to `.env.keys`. This is useful with monorepos.
723
1279
 
724
- ```sh
725
- $ echo "HELLO=World" > .env
726
- $ dotenvx encrypt --stdout
727
- $ dotenvx encrypt --stdout > .env.encrypted
728
- ```
1280
+ ```sh
1281
+ $ mkdir -p apps/app1
1282
+ $ touch apps/app1/.env
1283
+ $ dotenvx set HELLO world -fk .env.keys -f apps/app1/.env
729
1284
 
730
- </details>
1285
+ $ dotenvx get HELLO -fk .env.keys -f apps/app1/.env
1286
+ world
1287
+ ```
731
1288
 
732
- * <details><summary>other curves</summary><br>
1289
+ </details>
1290
+ <details><summary>`get KEY --env`</summary><br>
733
1291
 
734
- > `secp256k1` is a well-known and battle tested curve, in use with Bitcoin and other cryptocurrencies, but we are open to adding support for more curves.
735
- >
736
- > If your organization's compliance department requires [NIST approved curves](https://csrc.nist.gov/projects/elliptic-curve-cryptography) or other curves like `curve25519`, please reach out at [security@dotenvx.com](mailto:security@dotenvx.com).
1292
+ Return a single environment variable's value from a `--env` string.
737
1293
 
738
- </details>
1294
+ ```sh
1295
+ $ dotenvx get HELLO --env HELLO=String -f .env.production
1296
+ String
1297
+ ```
739
1298
 
740
- &nbsp;
1299
+ </details>
741
1300
 
742
- ## Advanced
1301
+ <details><summary>`get KEY --overload`</summary><br>
743
1302
 
744
- > Become a `dotenvx` power user.
745
- >
1303
+ Return a single environment variable's value where each found value is overloaded.
746
1304
 
747
- ### CLI 📟
1305
+ ```sh
1306
+ $ echo "HELLO=World" > .env
1307
+ $ echo "HELLO=production" > .env.production
748
1308
 
749
- Advanced CLI commands.
1309
+ $ dotenvx get HELLO -f .env.production --env HELLO=String -f .env --overload
1310
+ World
1311
+ ```
750
1312
 
751
- * <details><summary>`run` - Variable Expansion</summary><br>
752
-
753
- Reference and expand variables already on your machine for use in your .env file.
754
-
755
- ```ini
756
- # .env
757
- USERNAME="username"
758
- DATABASE_URL="postgres://${USERNAME}@localhost/my_database"
759
- ```
760
- ```js
761
- // index.js
762
- console.log('DATABASE_URL', process.env.DATABASE_URL)
763
- ```
764
- ```sh
765
- $ dotenvx run --debug -- node index.js
766
- [dotenvx@1.X.X] injecting env (2) from .env
767
- DATABASE_URL postgres://username@localhost/my_database
768
- ```
769
-
770
- </details>
771
- * <details><summary>`run` - Default Values</summary><br>
772
-
773
- Use default values when environment variables are unset or empty.
774
-
775
- ```ini
776
- # .env
777
- # Default value syntax: use value if set, otherwise use default
778
- DATABASE_HOST=${DB_HOST:-localhost}
779
- DATABASE_PORT=${DB_PORT:-5432}
780
-
781
- # Alternative syntax (no colon): use value if set, otherwise use default
782
- API_URL=${API_BASE_URL-https://api.example.com}
783
- ```
784
- ```js
785
- // index.js
786
- console.log('DATABASE_HOST', process.env.DATABASE_HOST)
787
- console.log('DATABASE_PORT', process.env.DATABASE_PORT)
788
- console.log('API_URL', process.env.API_URL)
789
- ```
790
- ```sh
791
- $ dotenvx run --debug -- node index.js
792
- [dotenvx@1.X.X] injecting env (3) from .env
793
- DATABASE_HOST localhost
794
- DATABASE_PORT 5432
795
- API_URL https://api.example.com
796
- ```
797
-
798
- </details>
799
- * <details><summary>`run` - Alternate Values</summary><br>
800
-
801
- Use alternate values when environment variables are set and non-empty.
802
-
803
- ```ini
804
- # .env
805
- NODE_ENV=production
806
-
807
- # Alternate value syntax: use alternate if set and non-empty, otherwise empty
808
- DEBUG_MODE=${NODE_ENV:+false}
809
- LOG_LEVEL=${NODE_ENV:+error}
810
-
811
- # Alternative syntax (no colon): use alternate if set, otherwise empty
812
- CACHE_ENABLED=${NODE_ENV+true}
813
- ```
814
- ```js
815
- // index.js
816
- console.log('NODE_ENV', process.env.NODE_ENV)
817
- console.log('DEBUG_MODE', process.env.DEBUG_MODE)
818
- console.log('LOG_LEVEL', process.env.LOG_LEVEL)
819
- console.log('CACHE_ENABLED', process.env.CACHE_ENABLED)
820
- ```
821
- ```sh
822
- $ dotenvx run --debug -- node index.js
823
- [dotenvx@1.X.X] injecting env (4) from .env
824
- NODE_ENV production
825
- DEBUG_MODE false
826
- LOG_LEVEL error
827
- CACHE_ENABLED true
828
- ```
829
-
830
- </details>
831
- * <details><summary>`run` - Interpolation Syntax Summary (Variable Expansion, Default/Alternate Values)</summary><br>
832
-
833
- Complete reference for variable interpolation patterns supported by dotenvx:
834
-
835
- ```ini
836
- # .env
837
- DEFINED_VAR=hello
838
- EMPTY_VAR=
839
- # UNDEFINED_VAR is not set
840
-
841
- # Default value syntax - use variable if set/non-empty, otherwise use default
842
- TEST1=${DEFINED_VAR:-fallback} # Result: "hello"
843
- TEST2=${EMPTY_VAR:-fallback} # Result: "fallback"
844
- TEST3=${UNDEFINED_VAR:-fallback} # Result: "fallback"
845
-
846
- # Default value syntax (no colon) - use variable if set, otherwise use default
847
- TEST4=${DEFINED_VAR-fallback} # Result: "hello"
848
- TEST5=${EMPTY_VAR-fallback} # Result: "" (empty, but set)
849
- TEST6=${UNDEFINED_VAR-fallback} # Result: "fallback"
850
-
851
- # Alternate value syntax - use alternate if variable is set/non-empty, otherwise empty
852
- TEST7=${DEFINED_VAR:+alternate} # Result: "alternate"
853
- TEST8=${EMPTY_VAR:+alternate} # Result: "" (empty)
854
- TEST9=${UNDEFINED_VAR:+alternate} # Result: "" (empty)
855
-
856
- # Alternate value syntax (no colon) - use alternate if variable is set, otherwise empty
857
- TEST10=${DEFINED_VAR+alternate} # Result: "alternate"
858
- TEST11=${EMPTY_VAR+alternate} # Result: "alternate" (empty but set)
859
- TEST12=${UNDEFINED_VAR+alternate} # Result: "" (empty)
860
- ```
861
-
862
- **Key differences:**
863
- - `:-` vs `-`: The colon makes empty values trigger the fallback
864
- - `:+` vs `+`: The colon makes empty values not trigger the alternate
865
- - Default syntax (`-`): Use variable value or fallback
866
- - Alternate syntax (`+`): Use alternate value or empty string
867
-
868
- </details>
869
- * <details><summary>`run` - Command Substitution</summary><br>
870
-
871
- Add the output of a command to one of your variables in your .env file.
872
-
873
- ```ini
874
- # .env
875
- DATABASE_URL="postgres://$(whoami)@localhost/my_database"
876
- ```
877
- ```js
878
- // index.js
879
- console.log('DATABASE_URL', process.env.DATABASE_URL)
880
- ```
881
- ```sh
882
- $ dotenvx run --debug -- node index.js
883
- [dotenvx@1.X.X] injecting env (1) from .env
884
- DATABASE_URL postgres://yourusername@localhost/my_database
885
- ```
1313
+ </details>
1314
+ <details><summary>`get KEY --strict`</summary><br>
886
1315
 
887
- </details>
888
- * <details><summary>`run` - Shell Expansion</summary><br>
1316
+ Exit with code `1` if any errors are encountered - like a missing key, missing .env file, or decryption failure.
889
1317
 
890
- Prevent your shell from expanding inline `$VARIABLES` before dotenvx has a chance to inject it. Use a subshell.
1318
+ ```sh
1319
+ $ dotenvx get DOES_NOT_EXIST --strict
1320
+ [MISSING_KEY] missing DOES_NOT_EXIST key
1321
+ ```
891
1322
 
892
- ```sh
893
- $ dotenvx run --env="HELLO=World" -- sh -c 'echo Hello $HELLO'
894
- Hello World
895
- ```
896
-
897
- </details>
898
- * <details><summary>`run` - Multiline</summary><br>
899
-
900
- Dotenvx supports multiline values. This is particularly useful in conjunction with Docker - which [does not support multiline values](https://stackoverflow.com/questions/50299617/set-multiline-environment-variable-with-dockerfile/79578348#79578348).
901
-
902
- ```ini
903
- # .env
904
- MULTILINE_PEM="-----BEGIN PUBLIC KEY-----
905
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u
906
- LgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/
907
- bTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/
908
- kKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V
909
- u4QuUoobAgMBAAE=
910
- -----END PUBLIC KEY-----"
911
- ```
912
-
913
- ```js
914
- // index.js
915
- console.log('MULTILINE_PEM', process.env.MULTILINE_PEM)
916
- ```
917
-
918
- ```sh
919
- $ dotenvx run -- node index.js
920
- MULTILINE_PEM -----BEGIN PUBLIC KEY-----
921
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u
922
- LgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/
923
- bTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/
924
- kKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V
925
- u4QuUoobAgMBAAE=
926
- -----END PUBLIC KEY-----
927
- ```
1323
+ </details>
1324
+ <details><summary>`get KEY --convention=nextjs`</summary><br>
928
1325
 
929
- </details>
930
- * <details><summary>`run` - Contextual Help</summary><br>
1326
+ Return a single environment variable's value using [Next.js' convention](https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#environment-variable-load-order). Set `--convention` to `nextjs`:
931
1327
 
932
- Unlike other dotenv libraries, dotenvx attempts to unblock you with contextual help.
1328
+ ```sh
1329
+ $ echo "HELLO=development local" > .env.development.local
1330
+ $ echo "HELLO=local" > .env.local
1331
+ $ echo "HELLO=development" > .env.development
1332
+ $ echo "HELLO=env" > .env
1333
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
933
1334
 
934
- For example, when missing a custom .env file:
1335
+ $ dotenvx get HELLO --convention=nextjs
1336
+ development local
1337
+ ```
935
1338
 
936
- ```sh
937
- $ dotenvx run -f .env.missing -- echo $HELLO
938
- [MISSING_ENV_FILE] missing .env.missing file (/Users/scottmotte/Code/dotenvx/playground/apr-16/.env.missing)
939
- [MISSING_ENV_FILE] https://github.com/dotenvx/dotenvx/issues/484 and re-run [dotenvx run -- echo]
940
- ```
1339
+ </details>
1340
+ <details><summary>`get KEY --convention=flow`</summary><br>
941
1341
 
942
- or when missing a KEY:
1342
+ Return a single environment variable's value using [dotenv-flow's convention](https://www.npmjs.com/package/dotenv-flow). Set `--convention` to `flow`:
943
1343
 
944
- ```sh
945
- $ echo "HELLO=World" > .env
946
- $ dotenvx get GOODBYE
947
- [MISSING_KEY] missing GOODBYE key
948
- ```
1344
+ ```sh
1345
+ $ echo "HELLO=development local" > .env.development.local
1346
+ $ echo "HELLO=development" > .env.development
1347
+ $ echo "HELLO=local" > .env.local
1348
+ $ echo "HELLO=env" > .env
1349
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
949
1350
 
950
- </details>
951
- * <details><summary>`run` - multiple `-f` flags</summary><br>
1351
+ $ NODE_ENV=development dotenvx get HELLO --convention=flow
1352
+ development local
1353
+ ```
952
1354
 
953
- Compose multiple `.env` files for environment variables loading, as you need.
1355
+ Further, we recommend using `DOTENV_ENV` over `NODE_ENV`– as `dotenvx` works everywhere, not just node.
954
1356
 
955
- ```sh
956
- $ echo "HELLO=local" > .env.local
957
- $ echo "HELLO=World" > .env
958
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1357
+ ```sh
1358
+ $ DOTENV_ENV=development dotenvx get HELLO --convention=flow
1359
+ development local
1360
+ ```
959
1361
 
960
- $ dotenvx run -f .env.local -f .env -- node index.js
961
- [dotenvx@1.X.X] injecting env (1) from .env.local, .env
962
- Hello local
963
- ```
1362
+ </details>
1363
+ <details><summary>`get` (json)</summary><br>
964
1364
 
965
- Note subsequent files do NOT override pre-existing variables defined in previous files or env. This follows historic principle. For example, above `local` wins – from the first file.
1365
+ Return a json response of all key/value pairs in a `.env` file.
966
1366
 
967
- </details>
968
- * <details><summary>`run --env HELLO=String`</summary><br>
1367
+ ```sh
1368
+ $ echo "HELLO=World" > .env
969
1369
 
970
- Set environment variables as a simple `KEY=value` string pair.
1370
+ $ dotenvx get
1371
+ {"HELLO":"World"}
1372
+ ```
971
1373
 
972
- ```sh
973
- $ echo "HELLO=World" > .env
974
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1374
+ </details>
1375
+ <details><summary>`get --format shell`</summary><br>
975
1376
 
976
- $ dotenvx run --env HELLO=String -f .env -- node index.js
977
- [dotenvx@1.X.X] injecting env (1) from .env, and --env flag
978
- Hello String
979
- ```
1377
+ Return a shell formatted response of all key/value pairs in a `.env` file.
980
1378
 
981
- </details>
982
- * <details><summary>`run --overload`</summary><br>
1379
+ ```sh
1380
+ $ echo "HELLO=World" > .env
1381
+ $ echo "KEY=value" >> .env
983
1382
 
984
- Override existing env variables. These can be variables already on your machine or variables loaded as files consecutively. The last variable seen will 'win'.
1383
+ $ dotenvx get --format shell
1384
+ HELLO=World KEY=value
1385
+ ```
985
1386
 
986
- ```sh
987
- $ echo "HELLO=local" > .env.local
988
- $ echo "HELLO=World" > .env
989
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1387
+ This can be useful when combined with `env` on the command line.
990
1388
 
991
- $ dotenvx run -f .env.local -f .env --overload -- node index.js
992
- [dotenvx@1.X.X] injecting env (1) from .env.local, .env
993
- Hello World
994
- ```
1389
+ ```
1390
+ $ echo "console.log('Hello ' + process.env.KEY + ' ' + process.env.HELLO)" > index.js
1391
+ $ env $(dotenvx get --format=shell) node index.js
1392
+ Hello value World
1393
+ ```
995
1394
 
996
- Note that with `--overload` subsequent files DO override pre-existing variables defined in previous files.
1395
+ or with `export`.
997
1396
 
998
- </details>
999
- * <details><summary>`run` - Environment Variable Precedence (Container/Cloud Deployments)</summary><br>
1397
+ ```
1398
+ $ echo "console.log('Hello ' + process.env.KEY + ' ' + process.env.HELLO)" > index.js
1399
+ $ export $(dotenvx get --format=shell)
1400
+ $ node index.js
1401
+ Hello value World
1402
+ ```
1000
1403
 
1001
- When deploying applications in containers or cloud environments, you often need to override specific environment variables at runtime without modifying committed `.env` files. By default, dotenvx follows the historic dotenv principle: **environment variables already present take precedence over `.env` files**.
1404
+ </details>
1405
+ <details><summary>`get --format eval`</summary><br>
1002
1406
 
1003
- ```sh
1004
- # .env.prod contains: MODEL_REGISTRY=registry.company.com/models/v1
1005
- $ echo "MODEL_REGISTRY=registry.company.com/models/v1" > .env.prod
1006
- $ echo "console.log('MODEL_REGISTRY:', process.env.MODEL_REGISTRY)" > app.js
1407
+ Return an `eval`-ready shell formatted response of all key/value pairs in a `.env` file.
1007
1408
 
1008
- # Without environment variable set - uses .env.prod value
1009
- $ dotenvx run -f .env.prod -- node app.js
1010
- MODEL_REGISTRY: registry.company.com/models/v1
1409
+ ```sh
1410
+ $ echo "HELLO=World" > .env
1411
+ $ echo "KEY=value" >> .env
1011
1412
 
1012
- # With environment variable set (e.g., via Azure Container Service) - environment variable takes precedence
1013
- $ MODEL_REGISTRY=registry.azure.com/models/v2 dotenvx run -f .env.prod -- node app.js
1014
- MODEL_REGISTRY: registry.azure.com/models/v2
1413
+ $ dotenvx get --format eval
1414
+ HELLO="World"
1415
+ KEY="value"
1416
+ ```
1015
1417
 
1016
- # To force .env.prod to override environment variables, use --overload
1017
- $ MODEL_REGISTRY=registry.azure.com/models/v2 dotenvx run -f .env.prod --overload -- node app.js
1018
- MODEL_REGISTRY: registry.company.com/models/v1
1019
- ```
1418
+ Note that this exports newlines and quoted strings.
1020
1419
 
1021
- **For container deployments:** Set environment variables through your cloud provider's UI/configuration (Azure Container Service, AWS ECS, etc.) to override specific values from committed `.env` files without rebuilding your application.
1420
+ This can be useful for more complex .env values (spaces, escaped characters, quotes, etc) combined with `eval` on the command line.
1022
1421
 
1023
- </details>
1024
- * <details><summary>`DOTENV_PRIVATE_KEY=key run`</summary><br>
1025
-
1026
- Decrypt your encrypted `.env` by setting `DOTENV_PRIVATE_KEY` before `dotenvx run`.
1422
+ ```sh
1423
+ $ echo "console.log('Hello ' + process.env.KEY + ' ' + process.env.HELLO)" > index.js
1424
+ $ eval $(dotenvx get --format=eval) node index.js
1425
+ Hello value World
1426
+ ```
1027
1427
 
1028
- ```sh
1029
- $ touch .env
1030
- $ dotenvx set HELLO encrypted
1031
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1428
+ Be careful with `eval` as it allows for arbitrary execution of commands. Prefer `dotenvx run --` but in some cases `eval` is a sharp knife that is useful to have.
1032
1429
 
1033
- # check your .env.keys files for your privateKey
1034
- $ DOTENV_PRIVATE_KEY="122...0b8" dotenvx run -- node index.js
1035
- [dotenvx@1.X.X] injecting env (2) from .env
1036
- Hello encrypted
1037
- ```
1430
+ </details>
1038
1431
 
1039
- </details>
1040
- * <details><summary>`DOTENV_PRIVATE_KEY_PRODUCTION=key run`</summary><br>
1432
+ <details><summary>`get --all`</summary><br>
1041
1433
 
1042
- Decrypt your encrypted `.env.production` by setting `DOTENV_PRIVATE_KEY_PRODUCTION` before `dotenvx run`. Alternatively, this can be already set on your server or cloud provider.
1434
+ Return preset machine envs as well.
1043
1435
 
1044
- ```sh
1045
- $ touch .env.production
1046
- $ dotenvx set HELLO "production encrypted" -f .env.production
1047
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1436
+ ```sh
1437
+ $ echo "HELLO=World" > .env
1048
1438
 
1049
- # check .env.keys for your privateKey
1050
- $ DOTENV_PRIVATE_KEY_PRODUCTION="122...0b8" dotenvx run -- node index.js
1051
- [dotenvx@1.X.X] injecting env (2) from .env.production
1052
- Hello production encrypted
1053
- ```
1439
+ $ dotenvx get --all
1440
+ {"PWD":"/some/file/path","USER":"username","LIBRARY_PATH":"/usr/local/lib", ..., "HELLO":"World"}
1441
+ ```
1054
1442
 
1055
- Note the `DOTENV_PRIVATE_KEY_PRODUCTION` ends with `_PRODUCTION`. This instructs dotenvx run to load the `.env.production` file.
1443
+ </details>
1444
+ <details><summary>`get --all --pretty-print`</summary><br>
1056
1445
 
1057
- </details>
1058
- * <details><summary>`DOTENV_PRIVATE_KEY_CI=key dotenvx run`</summary><br>
1446
+ Make the output more readable - pretty print it.
1059
1447
 
1060
- Decrypt your encrypted `.env.ci` by setting `DOTENV_PRIVATE_KEY_CI` before `dotenvx run`. Alternatively, this can be already set on your server or cloud provider.
1448
+ ```sh
1449
+ $ echo "HELLO=World" > .env
1061
1450
 
1062
- ```sh
1063
- $ touch .env.ci
1064
- $ dotenvx set HELLO "ci encrypted" -f .env.ci
1065
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1451
+ $ dotenvx get --all --pretty-print
1452
+ {
1453
+ "PWD": "/some/filepath",
1454
+ "USER": "username",
1455
+ "LIBRARY_PATH": "/usr/local/lib",
1456
+ ...,
1457
+ "HELLO": "World"
1458
+ }
1459
+ ```
1066
1460
 
1067
- # check .env.keys for your privateKey
1068
- $ DOTENV_PRIVATE_KEY_CI="122...0b8" dotenvx run -- node index.js
1069
- [dotenvx@1.X.X] injecting env (2) from .env.ci
1070
- Hello ci encrypted
1071
- ```
1461
+ </details>
1462
+ <details><summary>`set KEY value`</summary><br>
1072
1463
 
1073
- Note the `DOTENV_PRIVATE_KEY_CI` ends with `_CI`. This instructs dotenvx run to load the `.env.ci` file. See the pattern?
1464
+ Set an encrypted key/value (on by default).
1074
1465
 
1075
- </details>
1076
- * <details><summary>`DOTENV_PRIVATE_KEY=key DOTENV_PRIVATE_KEY_PRODUCTION=key run` - Combine Multiple</summary><br>
1466
+ ```sh
1467
+ $ touch .env
1077
1468
 
1078
- Decrypt your encrypted `.env` and `.env.production` files by setting `DOTENV_PRIVATE_KEY` and `DOTENV_PRIVATE_KEY_PRODUCTION` before `dotenvx run`.
1469
+ $ dotenvx set HELLO World
1470
+ set HELLO with encryption (.env)
1471
+ ```
1079
1472
 
1080
- ```sh
1081
- $ touch .env
1082
- $ touch .env.production
1083
- $ dotenvx set HELLO encrypted
1084
- $ dotenvx set HELLO "production encrypted" -f .env.production
1085
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1473
+ </details>
1474
+ <details><summary>`set KEY value -f`</summary><br>
1086
1475
 
1087
- # check .env.keys for your privateKeys
1088
- $ DOTENV_PRIVATE_KEY="122...0b8" DOTENV_PRIVATE_KEY_PRODUCTION="122...0b8" dotenvx run -- node index.js
1089
- [dotenvx@1.X.X] injecting env (3) from .env, .env.production
1090
- Hello encrypted
1476
+ Set an (encrypted) key/value for another `.env` file.
1091
1477
 
1092
- $ DOTENV_PRIVATE_KEY_PRODUCTION="122...0b8" DOTENV_PRIVATE_KEY="122...0b8" dotenvx run -- node index.js
1093
- [dotenvx@1.X.X] injecting env (3) from .env.production, .env
1094
- Hello production encrypted
1095
- ```
1478
+ ```sh
1479
+ $ touch .env.production
1096
1480
 
1097
- Compose any encrypted files you want this way. As long as a `DOTENV_PRIVATE_KEY_${environment}` is set, the values from `.env.${environment}` will be decrypted at runtime.
1481
+ $ dotenvx set HELLO production -f .env.production
1482
+ set HELLO with encryption (.env.production)
1483
+ ```
1098
1484
 
1099
- </details>
1100
- * <details><summary>`run --verbose`</summary><br>
1485
+ </details>
1486
+ <details><summary>`set KEY value -fk`</summary><br>
1101
1487
 
1102
- Set log level to `verbose`. ([log levels](https://docs.npmjs.com/cli/v8/using-npm/logging#setting-log-levels))
1488
+ Specify path to `.env.keys`. This is useful with monorepos.
1103
1489
 
1104
- ```sh
1105
- $ echo "HELLO=production" > .env.production
1106
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1490
+ ```sh
1491
+ $ mkdir -p apps/app1
1492
+ $ touch apps/app1/.env
1107
1493
 
1108
- $ dotenvx run -f .env.production --verbose -- node index.js
1109
- loading env from .env.production (/path/to/.env.production)
1110
- HELLO set
1111
- [dotenvx@1.X.X] injecting env (1) from .env.production
1112
- Hello production
1113
- ```
1494
+ $ dotenvx set HELLO world -fk .env.keys -f apps/app1/.env
1495
+ set HELLO with encryption (.env)
1496
+ ```
1114
1497
 
1115
- </details>
1116
- * <details><summary>`run --debug`</summary><br>
1498
+ Put it to use.
1117
1499
 
1118
- Set log level to `debug`. ([log levels](https://docs.npmjs.com/cli/v8/using-npm/logging#setting-log-levels))
1500
+ ```sh
1501
+ $ dotenvx get -fk .env.keys -f apps/app1/.env
1502
+ ```
1119
1503
 
1120
- ```sh
1121
- $ echo "HELLO=production" > .env.production
1122
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1504
+ Use it with a relative path.
1123
1505
 
1124
- $ dotenvx run -f .env.production --debug -- node index.js
1125
- process command [node index.js]
1126
- options: {"env":[],"envFile":[".env.production"]}
1127
- loading env from .env.production (/path/to/.env.production)
1128
- {"HELLO":"production"}
1129
- HELLO set
1130
- HELLO set to production
1131
- [dotenvx@1.X.X] injecting env (1) from .env.production
1132
- executing process command [node index.js]
1133
- expanding process command to [/opt/homebrew/bin/node index.js]
1134
- Hello production
1135
- ```
1136
-
1137
- </details>
1138
- * <details><summary>`run --quiet`</summary><br>
1139
-
1140
- Use `--quiet` to suppress all output (except errors). ([log levels](https://docs.npmjs.com/cli/v8/using-npm/logging#setting-log-levels))
1141
-
1142
- ```sh
1143
- $ echo "HELLO=production" > .env.production
1144
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1506
+ ```sh
1507
+ $ cd apps/app1
1508
+ $ dotenvx get -fk ../../.env.keys -f .env
1509
+ ```
1145
1510
 
1146
- $ dotenvx run -f .env.production --quiet -- node index.js
1147
- Hello production
1148
- ```
1511
+ </details>
1512
+ <details><summary>`set KEY "value with spaces"`</summary><br>
1149
1513
 
1150
- </details>
1151
- * <details><summary>`run --log-level`</summary><br>
1514
+ Set a value containing spaces.
1152
1515
 
1153
- Set `--log-level` to whatever you wish. For example, to suppress warnings (risky), set log level to `error`:
1516
+ ```sh
1517
+ $ touch .env.ci
1154
1518
 
1155
- ```sh
1156
- $ echo "HELLO=production" > .env.production
1157
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1519
+ $ dotenvx set HELLO "my ci" -f .env.ci
1520
+ set HELLO with encryption (.env.ci)
1521
+ ```
1158
1522
 
1159
- $ dotenvx run -f .env.production --log-level=error -- node index.js
1160
- Hello production
1161
- ```
1523
+ </details>
1524
+ <details><summary>`set KEY -- "- + * ÷"`</summary><br>
1162
1525
 
1163
- Available log levels are `error, warn, info, verbose, debug, silly` ([source](https://docs.npmjs.com/cli/v8/using-npm/logging#setting-log-levels))
1526
+ If your value starts with a dash (`-`), then place two dashes instructing the cli that there are no more flag arguments.
1164
1527
 
1165
- </details>
1166
- * <details><summary>`run --strict`</summary><br>
1528
+ ```sh
1529
+ $ touch .env.ci
1167
1530
 
1168
- Exit with code `1` if any errors are encountered - like a missing .env file or decryption failure.
1531
+ $ dotenvx set HELLO -f .env.ci -- "- + * ÷"
1532
+ set HELLO with encryption (.env.ci)
1533
+ ```
1169
1534
 
1170
- ```sh
1171
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1535
+ </details>
1536
+ <details><summary>`set KEY value --plain`</summary><br>
1172
1537
 
1173
- $ dotenvx run -f .env.missing --strict -- node index.js
1174
- [MISSING_ENV_FILE] missing .env.missing file (/path/to/.env.missing)
1175
- [MISSING_ENV_FILE] ? add one with [echo "HELLO=World" > .env.missing]
1176
- ```
1538
+ Set a plaintext key/value.
1177
1539
 
1178
- This can be useful in `ci` scripts where you want to fail the ci if your `.env` file could not be decrypted at runtime.
1540
+ ```sh
1541
+ $ touch .env
1179
1542
 
1180
- </details>
1181
- * <details><summary>`run --ignore`</summary><br>
1543
+ $ dotenvx set HELLO World --plain
1544
+ set HELLO (.env)
1545
+ ```
1182
1546
 
1183
- Ignore errors like `MISSING_ENV_FILE`.
1547
+ </details>
1548
+ <details><summary>`encrypt`</summary><br>
1184
1549
 
1185
- ```sh
1186
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1550
+ Encrypt the contents of a `.env` file to an encrypted `.env` file.
1187
1551
 
1188
- $ dotenvx run -f .env.missing --ignore=MISSING_ENV_FILE -- node index.js
1189
- ...
1190
- ```
1552
+ ```sh
1553
+ $ echo "HELLO=World" > .env
1191
1554
 
1192
- </details>
1193
- * <details><summary>`run --convention=nextjs`</summary><br>
1555
+ $ dotenvx encrypt
1556
+ encrypted (.env)
1557
+ ✔ key added to .env.keys (DOTENV_PRIVATE_KEY)
1558
+ ⮕ next run [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys
1559
+ ⮕ next run [DOTENV_PRIVATE_KEY='122...0b8' dotenvx run -- yourcommand] to test decryption locally
1560
+ ```
1194
1561
 
1195
- Load envs using [Next.js' convention](https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#environment-variable-load-order). Set `--convention` to `nextjs`:
1562
+ </details>
1563
+ <details><summary>`encrypt -f`</summary><br>
1196
1564
 
1197
- ```sh
1198
- $ echo "HELLO=development local" > .env.development.local
1199
- $ echo "HELLO=local" > .env.local
1200
- $ echo "HELLO=development" > .env.development
1201
- $ echo "HELLO=env" > .env
1202
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1565
+ Encrypt the contents of a specified `.env` file to an encrypted `.env` file.
1203
1566
 
1204
- $ dotenvx run --convention=nextjs -- node index.js
1205
- [dotenvx@1.X.X] injecting env (1) from .env.development.local, .env.local, .env.development, .env
1206
- Hello development local
1207
- ```
1567
+ ```sh
1568
+ $ echo "HELLO=World" > .env
1569
+ $ echo "HELLO=Production" > .env.production
1208
1570
 
1209
- (more conventions available upon request)
1571
+ $ dotenvx encrypt -f .env.production
1572
+ ✔ encrypted (.env.production)
1573
+ ✔ key added to .env.keys (DOTENV_PRIVATE_KEY_PRODUCTION)
1574
+ ⮕ next run [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys
1575
+ ⮕ next run [DOTENV_PRIVATE_KEY='bff...bc4' dotenvx run -- yourcommand] to test decryption locally
1576
+ ```
1210
1577
 
1211
- </details>
1212
- * <details><summary>`run --convention=flow`</summary><br>
1578
+ </details>
1579
+ <details><summary>`encrypt -fk`</summary><br>
1213
1580
 
1214
- Load envs using [dotenv-flow's convention](https://www.npmjs.com/package/dotenv-flow). Set `--convention` to `flow`:
1581
+ Specify path to `.env.keys`. This is useful with monorepos.
1215
1582
 
1216
- ```sh
1217
- $ echo "HELLO=development local" > .env.development.local
1218
- $ echo "HELLO=development" > .env.development
1219
- $ echo "HELLO=local" > .env.local
1220
- $ echo "HELLO=env" > .env
1221
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1583
+ ```sh
1584
+ $ mkdir -p apps/app1
1585
+ $ echo "HELLO=World" > apps/app1/.env
1222
1586
 
1223
- $ NODE_ENV=development dotenvx run --convention=flow -- node index.js
1224
- [dotenvx@1.X.X] injecting env (1) from .env.development.local, .env.development, .env.local, .env
1225
- Hello development local
1226
- ```
1587
+ $ dotenvx encrypt -fk .env.keys -f apps/app1/.env
1588
+ encrypted (apps/app1/.env)
1589
+ ```
1227
1590
 
1228
- Further, we recommend using `DOTENV_ENV` over `NODE_ENV`– as `dotenvx` works everywhere, not just node.
1591
+ Put it to use.
1229
1592
 
1230
- ```sh
1231
- $ DOTENV_ENV=development dotenvx run --convention=flow -- node index.js
1232
- [dotenvx@1.X.X] injecting env (1) from .env.development.local, .env.development, .env.local, .env
1233
- Hello development local
1234
- ```
1593
+ ```sh
1594
+ $ dotenvx run -fk .env.keys -f apps/app1/.env
1595
+ ```
1235
1596
 
1236
- </details>
1237
- * <details><summary>`run -fk`</summary><br>
1597
+ Use with a relative path.
1238
1598
 
1239
- Specify path to `.env.keys`. This is useful with monorepos.
1599
+ ```sh
1600
+ $ cd apps/app1
1601
+ $ dotenvx run -fk ../../.env.keys -f .env
1602
+ ```
1240
1603
 
1241
- ```sh
1242
- $ mkdir -p apps/app1
1243
- $ touch apps/app1/.env
1244
- $ dotenvx set HELLO world -fk .env.keys -f apps/app1/.env
1604
+ </details>
1605
+ <details><summary>`encrypt -k`</summary><br>
1245
1606
 
1246
- $ dotenvx run -fk .env.keys -f apps/app1/.env -- yourcommand
1247
- ```
1607
+ Specify the key(s) to encrypt by passing `--key`.
1248
1608
 
1249
- </details>
1250
- * <details><summary>`get KEY`</summary><br>
1609
+ ```sh
1610
+ $ echo "HELLO=World\nHELLO2=Universe" > .env
1251
1611
 
1252
- Return a single environment variable's value.
1612
+ $ dotenvx encrypt -k HELLO2
1613
+ ✔ encrypted (.env)
1614
+ ```
1253
1615
 
1254
- ```sh
1255
- $ echo "HELLO=World" > .env
1616
+ Even specify a glob pattern.
1256
1617
 
1257
- $ dotenvx get HELLO
1258
- World
1259
- ```
1618
+ ```sh
1619
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1260
1620
 
1261
- </details>
1262
- * <details><summary>`get KEY -f`</summary><br>
1621
+ $ dotenvx encrypt -k "HE*"
1622
+ encrypted (.env)
1623
+ ```
1263
1624
 
1264
- Return a single environment variable's value from a specific `.env` file.
1625
+ </details>
1626
+ <details><summary>`encrypt -ek`</summary><br>
1265
1627
 
1266
- ```sh
1267
- $ echo "HELLO=World" > .env
1268
- $ echo "HELLO=production" > .env.production
1628
+ Specify the key(s) to NOT encrypt by passing `--exclude-key`.
1269
1629
 
1270
- $ dotenvx get HELLO -f .env.production
1271
- production
1272
- ```
1630
+ ```sh
1631
+ $ echo "HELLO=World\nHELLO2=Universe" > .env
1273
1632
 
1274
- </details>
1275
- * <details><summary>`get KEY -fk`</summary><br>
1633
+ $ dotenvx encrypt -ek HELLO
1634
+ encrypted (.env)
1635
+ ```
1276
1636
 
1277
- Specify path to `.env.keys`. This is useful with monorepos.
1637
+ Even specify a glob pattern.
1278
1638
 
1279
- ```sh
1280
- $ mkdir -p apps/app1
1281
- $ touch apps/app1/.env
1282
- $ dotenvx set HELLO world -fk .env.keys -f apps/app1/.env
1639
+ ```sh
1640
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1283
1641
 
1284
- $ dotenvx get HELLO -fk .env.keys -f apps/app1/.env
1285
- world
1286
- ```
1642
+ $ dotenvx encrypt -ek "HO*"
1643
+ ✔ encrypted (.env)
1644
+ ```
1287
1645
 
1288
- </details>
1289
- * <details><summary>`get KEY --env`</summary><br>
1646
+ </details>
1647
+ <details><summary>`encrypt --stdout`</summary><br>
1290
1648
 
1291
- Return a single environment variable's value from a `--env` string.
1649
+ Encrypt the contents of a `.env` file and send to stdout.
1292
1650
 
1293
- ```sh
1294
- $ dotenvx get HELLO --env HELLO=String -f .env.production
1295
- String
1296
- ```
1651
+ ```sh
1652
+ $ echo "HELLO=World" > .env
1653
+ $ dotenvx encrypt --stdout
1654
+ #/-------------------[DOTENV_PUBLIC_KEY]--------------------/
1655
+ #/ public-key encryption for .env files /
1656
+ #/ [how it works](https://dotenvx.com/encryption) /
1657
+ #/----------------------------------------------------------/
1658
+ DOTENV_PUBLIC_KEY="034af93e93708b994c10f236c96ef88e47291066946cce2e8d98c9e02c741ced45"
1659
+ # .env
1660
+ HELLO="encrypted:BDqDBibm4wsYqMpCjTQ6BsDHmMadg9K3dAt+Z9HPMfLEIRVz50hmLXPXRuDBXaJi/LwWYEVUNiq0HISrslzQPaoyS8Lotg3gFWJTsNCdOWnqpjF2xNUX2RQiP05kAbEXM6MWVjDr"
1661
+ ```
1297
1662
 
1298
- </details>
1663
+ or send to a file:
1299
1664
 
1300
- * <details><summary>`get KEY --overload`</summary><br>
1665
+ ```sh
1666
+ $ echo "HELLO=World" > .env
1667
+ $ dotenvx encrypt --stdout > somefile.txt
1668
+ ```
1301
1669
 
1302
- Return a single environment variable's value where each found value is overloaded.
1670
+ </details>
1671
+ <details><summary>`decrypt`</summary><br>
1303
1672
 
1304
- ```sh
1305
- $ echo "HELLO=World" > .env
1306
- $ echo "HELLO=production" > .env.production
1673
+ Decrypt the contents of an encrypted `.env` file to an unencrypted `.env` file.
1307
1674
 
1308
- $ dotenvx get HELLO -f .env.production --env HELLO=String -f .env --overload
1309
- World
1310
- ```
1675
+ ```sh
1676
+ $ echo "HELLO=World" > .env
1677
+ $ dotenvx encrypt
1678
+ ✔ encrypted (.env)
1679
+ $ dotenvx decrypt
1680
+ ✔ decrypted (.env)
1681
+ ```
1311
1682
 
1312
- </details>
1313
- * <details><summary>`get KEY --strict`</summary><br>
1683
+ </details>
1684
+ <details><summary>`decrypt -f`</summary><br>
1314
1685
 
1315
- Exit with code `1` if any errors are encountered - like a missing key, missing .env file, or decryption failure.
1686
+ Decrypt the contents of a specified encrypted `.env` file to an unencrypted `.env` file.
1316
1687
 
1317
- ```sh
1318
- $ dotenvx get DOES_NOT_EXIST --strict
1319
- [MISSING_KEY] missing DOES_NOT_EXIST key
1320
- ```
1688
+ ```sh
1689
+ $ echo "HELLO=World" > .env
1690
+ $ echo "HELLO=Production" > .env.production
1321
1691
 
1322
- </details>
1323
- * <details><summary>`get KEY --convention=nextjs`</summary><br>
1692
+ $ dotenvx encrypt -f .env.production
1693
+ encrypted (.env.production)
1694
+ $ dotenvx decrypt -f .env.production
1695
+ ✔ decrypted (.env.production)
1696
+ ```
1324
1697
 
1325
- Return a single environment variable's value using [Next.js' convention](https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#environment-variable-load-order). Set `--convention` to `nextjs`:
1698
+ </details>
1699
+ <details><summary>`decrypt -fk`</summary><br>
1326
1700
 
1327
- ```sh
1328
- $ echo "HELLO=development local" > .env.development.local
1329
- $ echo "HELLO=local" > .env.local
1330
- $ echo "HELLO=development" > .env.development
1331
- $ echo "HELLO=env" > .env
1332
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1701
+ Specify path to `.env.keys`. This is useful with monorepos.
1333
1702
 
1334
- $ dotenvx get HELLO --convention=nextjs
1335
- development local
1336
- ```
1703
+ ```sh
1704
+ $ mkdir -p apps/app1
1705
+ $ echo "HELLO=World" > apps/app1/.env
1337
1706
 
1338
- </details>
1339
- * <details><summary>`get KEY --convention=flow`</summary><br>
1707
+ $ dotenvx encrypt -fk .env.keys -f apps/app1/.env
1708
+ encrypted (apps/app1/.env)
1709
+ $ dotenvx decrypt -fk .env.keys -f apps/app1/.env
1710
+ ✔ decrypted (apps/app1/.env)
1711
+ ```
1340
1712
 
1341
- Return a single environment variable's value using [dotenv-flow's convention](https://www.npmjs.com/package/dotenv-flow). Set `--convention` to `flow`:
1713
+ </details>
1714
+ <details><summary>`decrypt -k`</summary><br>
1342
1715
 
1343
- ```sh
1344
- $ echo "HELLO=development local" > .env.development.local
1345
- $ echo "HELLO=development" > .env.development
1346
- $ echo "HELLO=local" > .env.local
1347
- $ echo "HELLO=env" > .env
1348
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1716
+ Decrypt the contents of a specified key inside an encrypted `.env` file.
1349
1717
 
1350
- $ NODE_ENV=development dotenvx get HELLO --convention=flow
1351
- development local
1352
- ```
1718
+ ```sh
1719
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1720
+ $ dotenvx encrypt
1721
+ ✔ encrypted (.env)
1722
+ $ dotenvx decrypt -k HELLO
1723
+ ✔ decrypted (.env)
1724
+ ```
1353
1725
 
1354
- Further, we recommend using `DOTENV_ENV` over `NODE_ENV`– as `dotenvx` works everywhere, not just node.
1726
+ Even specify a glob pattern.
1355
1727
 
1356
- ```sh
1357
- $ DOTENV_ENV=development dotenvx get HELLO --convention=flow
1358
- development local
1359
- ```
1728
+ ```sh
1729
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1730
+ $ dotenvx encrypt
1731
+ ✔ encrypted (.env)
1732
+ $ dotenvx decrypt -k "HE*"
1733
+ ✔ encrypted (.env)
1734
+ ```
1360
1735
 
1361
- </details>
1362
- * <details><summary>`get` (json)</summary><br>
1736
+ </details>
1737
+ <details><summary>`decrypt -ek`</summary><br>
1363
1738
 
1364
- Return a json response of all key/value pairs in a `.env` file.
1739
+ Decrypt the contents inside an encrypted `.env` file except for an excluded key.
1365
1740
 
1366
- ```sh
1367
- $ echo "HELLO=World" > .env
1741
+ ```sh
1742
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1743
+ $ dotenvx encrypt
1744
+ ✔ encrypted (.env)
1745
+ $ dotenvx decrypt -ek HOLA
1746
+ ✔ decrypted (.env)
1747
+ ```
1368
1748
 
1369
- $ dotenvx get
1370
- {"HELLO":"World"}
1371
- ```
1749
+ Even specify a glob pattern.
1372
1750
 
1373
- </details>
1374
- * <details><summary>`get --format shell`</summary><br>
1751
+ ```sh
1752
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1753
+ $ dotenvx encrypt
1754
+ ✔ encrypted (.env)
1755
+ $ dotenvx decrypt -ek "HO*"
1756
+ ✔ encrypted (.env)
1757
+ ```
1375
1758
 
1376
- Return a shell formatted response of all key/value pairs in a `.env` file.
1759
+ </details>
1760
+ <details><summary>`decrypt --stdout`</summary><br>
1377
1761
 
1378
- ```sh
1379
- $ echo "HELLO=World" > .env
1380
- $ echo "KEY=value" >> .env
1762
+ Decrypt the contents of an encrypted `.env` file and send to stdout.
1381
1763
 
1382
- $ dotenvx get --format shell
1383
- HELLO=World KEY=value
1384
- ```
1764
+ ```sh
1765
+ $ dotenvx decrypt --stdout
1766
+ #/-------------------[DOTENV_PUBLIC_KEY]--------------------/
1767
+ #/ public-key encryption for .env files /
1768
+ #/ [how it works](https://dotenvx.com/encryption) /
1769
+ #/----------------------------------------------------------/
1770
+ DOTENV_PUBLIC_KEY="034af93e93708b994c10f236c96ef88e47291066946cce2e8d98c9e02c741ced45"
1771
+ # .env
1772
+ HELLO="World"
1773
+ ```
1385
1774
 
1386
- This can be useful when combined with `env` on the command line.
1775
+ or send to a file:
1387
1776
 
1388
- ```
1389
- $ echo "console.log('Hello ' + process.env.KEY + ' ' + process.env.HELLO)" > index.js
1390
- $ env $(dotenvx get --format=shell) node index.js
1391
- Hello value World
1392
- ```
1777
+ ```sh
1778
+ $ dotenvx decrypt --stdout > somefile.txt
1779
+ ```
1393
1780
 
1394
- or with `export`.
1781
+ </details>
1782
+ <details><summary>`keypair`</summary><br>
1395
1783
 
1396
- ```
1397
- $ echo "console.log('Hello ' + process.env.KEY + ' ' + process.env.HELLO)" > index.js
1398
- $ export $(dotenvx get --format=shell)
1399
- $ node index.js
1400
- Hello value World
1401
- ```
1784
+ Print public/private keys for `.env` file.
1402
1785
 
1403
- </details>
1404
- * <details><summary>`get --format eval`</summary><br>
1786
+ ```sh
1787
+ $ echo "HELLO=World" > .env
1788
+ $ dotenvx encrypt
1405
1789
 
1406
- Return an `eval`-ready shell formatted response of all key/value pairs in a `.env` file.
1790
+ $ dotenvx keypair
1791
+ {"DOTENV_PUBLIC_KEY":"<publicKey>","DOTENV_PRIVATE_KEY":"<privateKey>"}
1792
+ ```
1407
1793
 
1408
- ```sh
1409
- $ echo "HELLO=World" > .env
1410
- $ echo "KEY=value" >> .env
1794
+ </details>
1795
+ <details><summary>`keypair -f`</summary><br>
1411
1796
 
1412
- $ dotenvx get --format eval
1413
- HELLO="World"
1414
- KEY="value"
1415
- ```
1797
+ Print public/private keys for `.env.production` file.
1416
1798
 
1417
- Note that this exports newlines and quoted strings.
1799
+ ```sh
1800
+ $ echo "HELLO=Production" > .env.production
1801
+ $ dotenvx encrypt -f .env.production
1418
1802
 
1419
- This can be useful for more complex .env values (spaces, escaped characters, quotes, etc) combined with `eval` on the command line.
1803
+ $ dotenvx keypair -f .env.production
1804
+ {"DOTENV_PUBLIC_KEY_PRODUCTION":"<publicKey>","DOTENV_PRIVATE_KEY_PRODUCTION":"<privateKey>"}
1805
+ ```
1420
1806
 
1421
- ```sh
1422
- $ echo "console.log('Hello ' + process.env.KEY + ' ' + process.env.HELLO)" > index.js
1423
- $ eval $(dotenvx get --format=eval) node index.js
1424
- Hello value World
1425
- ```
1807
+ </details>
1808
+ <details><summary>`keypair -fk`</summary><br>
1426
1809
 
1427
- Be careful with `eval` as it allows for arbitrary execution of commands. Prefer `dotenvx run --` but in some cases `eval` is a sharp knife that is useful to have.
1810
+ Specify path to `.env.keys`. This is useful for printing public/private keys for monorepos.
1428
1811
 
1429
- </details>
1812
+ ```sh
1813
+ $ mkdir -p apps/app1
1814
+ $ echo "HELLO=World" > apps/app1/.env
1815
+ $ dotenvx encrypt -fk .env.keys -f apps/app1/.env
1430
1816
 
1431
- * <details><summary>`get --all`</summary><br>
1817
+ $ dotenvx keypair -fk .env.keys -f apps/app1/.env
1818
+ {"DOTENV_PUBLIC_KEY":"<publicKey>","DOTENV_PRIVATE_KEY":"<privateKey>"}
1819
+ ```
1432
1820
 
1433
- Return preset machine envs as well.
1821
+ </details>
1822
+ <details><summary>`keypair DOTENV_PRIVATE_KEY`</summary><br>
1434
1823
 
1435
- ```sh
1436
- $ echo "HELLO=World" > .env
1824
+ Print specific keypair for `.env` file.
1437
1825
 
1438
- $ dotenvx get --all
1439
- {"PWD":"/some/file/path","USER":"username","LIBRARY_PATH":"/usr/local/lib", ..., "HELLO":"World"}
1440
- ```
1826
+ ```sh
1827
+ $ echo "HELLO=World" > .env
1828
+ $ dotenvx encrypt
1441
1829
 
1442
- </details>
1443
- * <details><summary>`get --all --pretty-print`</summary><br>
1830
+ $ dotenvx keypair DOTENV_PRIVATE_KEY
1831
+ <privateKey>
1832
+ ```
1444
1833
 
1445
- Make the output more readable - pretty print it.
1834
+ </details>
1835
+ <details><summary>`keypair --format shell`</summary><br>
1446
1836
 
1447
- ```sh
1448
- $ echo "HELLO=World" > .env
1837
+ Print a shell formatted response of public/private keys.
1449
1838
 
1450
- $ dotenvx get --all --pretty-print
1451
- {
1452
- "PWD": "/some/filepath",
1453
- "USER": "username",
1454
- "LIBRARY_PATH": "/usr/local/lib",
1455
- ...,
1456
- "HELLO": "World"
1457
- }
1458
- ```
1839
+ ```sh
1840
+ $ echo "HELLO=World" > .env
1841
+ $ dotenx encrypt
1459
1842
 
1460
- </details>
1461
- * <details><summary>`set KEY value`</summary><br>
1843
+ $ dotenvx keypair --format shell
1844
+ DOTENV_PUBLIC_KEY=<publicKey> DOTENV_PRIVATE_KEY=<privateKey>
1845
+ ```
1462
1846
 
1463
- Set an encrypted key/value (on by default).
1847
+ </details>
1848
+ <details><summary>`ls`</summary><br>
1464
1849
 
1465
- ```sh
1466
- $ touch .env
1850
+ Print all `.env` files in a tree structure.
1467
1851
 
1468
- $ dotenvx set HELLO World
1469
- set HELLO with encryption (.env)
1470
- ```
1852
+ ```sh
1853
+ $ touch .env
1854
+ $ touch .env.production
1855
+ $ mkdir -p apps/backend
1856
+ $ touch apps/backend/.env
1857
+
1858
+ $ dotenvx ls
1859
+ ├─ .env.production
1860
+ ├─ .env
1861
+ └─ apps
1862
+ └─ backend
1863
+ └─ .env
1864
+ ```
1471
1865
 
1472
- </details>
1473
- * <details><summary>`set KEY value -f`</summary><br>
1866
+ </details>
1867
+ <details><summary>`ls directory`</summary><br>
1474
1868
 
1475
- Set an (encrypted) key/value for another `.env` file.
1869
+ Print all `.env` files inside a specified path to a directory.
1476
1870
 
1477
- ```sh
1478
- $ touch .env.production
1871
+ ```sh
1872
+ $ touch .env
1873
+ $ touch .env.production
1874
+ $ mkdir -p apps/backend
1875
+ $ touch apps/backend/.env
1479
1876
 
1480
- $ dotenvx set HELLO production -f .env.production
1481
- set HELLO with encryption (.env.production)
1482
- ```
1877
+ $ dotenvx ls apps/backend
1878
+ └─ .env
1879
+ ```
1483
1880
 
1484
- </details>
1485
- * <details><summary>`set KEY value -fk`</summary><br>
1881
+ </details>
1882
+ <details><summary>`ls -f`</summary><br>
1486
1883
 
1487
- Specify path to `.env.keys`. This is useful with monorepos.
1884
+ Glob `.env` filenames matching a wildcard.
1488
1885
 
1489
- ```sh
1490
- $ mkdir -p apps/app1
1491
- $ touch apps/app1/.env
1886
+ ```sh
1887
+ $ touch .env
1888
+ $ touch .env.production
1889
+ $ mkdir -p apps/backend
1890
+ $ touch apps/backend/.env
1891
+ $ touch apps/backend/.env.prod
1892
+
1893
+ $ dotenvx ls -f **/.env.prod*
1894
+ ├─ .env.production
1895
+ └─ apps
1896
+ └─ backend
1897
+ └─ .env.prod
1898
+ ```
1492
1899
 
1493
- $ dotenvx set HELLO world -fk .env.keys -f apps/app1/.env
1494
- set HELLO with encryption (.env)
1495
- ```
1900
+ </details>
1901
+ <details><summary>`ls -ef`</summary><br>
1496
1902
 
1497
- Put it to use.
1903
+ Glob `.env` filenames excluding a wildcard.
1498
1904
 
1499
- ```sh
1500
- $ dotenvx get -fk .env.keys -f apps/app1/.env
1501
- ```
1905
+ ```sh
1906
+ $ touch .env
1907
+ $ touch .env.production
1908
+ $ mkdir -p apps/backend
1909
+ $ touch apps/backend/.env
1910
+ $ touch apps/backend/.env.prod
1911
+
1912
+ $ dotenvx ls -ef '**/.env.prod*'
1913
+ ├─ .env
1914
+ └─ apps
1915
+ └─ backend
1916
+ └─ .env
1917
+ ```
1502
1918
 
1503
- Use it with a relative path.
1919
+ </details>
1920
+ <details><summary>`rotate`</summary><br>
1504
1921
 
1505
- ```sh
1506
- $ cd apps/app1
1507
- $ dotenvx get -fk ../../.env.keys -f .env
1508
- ```
1922
+ Rotate public/private keys for `.env` file and re-encrypt all encrypted values.
1509
1923
 
1510
- </details>
1511
- * <details><summary>`set KEY "value with spaces"`</summary><br>
1924
+ ```sh
1925
+ $ echo "HELLO=World" > .env
1926
+ $ dotenvx encrypt
1927
+ ✔ encrypted (.env)
1928
+ $ dotenvx rotate
1929
+ ✔ rotated (.env)
1930
+ ```
1512
1931
 
1513
- Set a value containing spaces.
1932
+ </details>
1933
+ <details><summary>`rotate -f`</summary><br>
1514
1934
 
1515
- ```sh
1516
- $ touch .env.ci
1935
+ Rotate public/private keys for a specified encrypted `.env` file and re-encrypt all encrypted values.
1517
1936
 
1518
- $ dotenvx set HELLO "my ci" -f .env.ci
1519
- set HELLO with encryption (.env.ci)
1520
- ```
1937
+ ```sh
1938
+ $ echo "HELLO=World" > .env
1939
+ $ echo "HELLO=Production" > .env.production
1521
1940
 
1522
- </details>
1523
- * <details><summary>`set KEY -- "- + * ÷"`</summary><br>
1941
+ $ dotenvx encrypt -f .env.production
1942
+ encrypted (.env.production)
1943
+ $ dotenvx rotate -f .env.production
1944
+ ✔ rotated (.env.production)
1945
+ ```
1524
1946
 
1525
- If your value starts with a dash (`-`), then place two dashes instructing the cli that there are no more flag arguments.
1947
+ </details>
1948
+ <details><summary>`rotate -fk`</summary><br>
1526
1949
 
1527
- ```sh
1528
- $ touch .env.ci
1950
+ Specify path to `.env.keys`. This is useful with monorepos.
1529
1951
 
1530
- $ dotenvx set HELLO -f .env.ci -- "- + * ÷"
1531
- set HELLO with encryption (.env.ci)
1532
- ```
1952
+ ```sh
1953
+ $ mkdir -p apps/app1
1954
+ $ echo "HELLO=World" > apps/app1/.env
1533
1955
 
1534
- </details>
1535
- * <details><summary>`set KEY value --plain`</summary><br>
1956
+ $ dotenvx encrypt -fk .env.keys -f apps/app1/.env
1957
+ encrypted (apps/app1/.env)
1958
+ $ dotenvx rotate -fk .env.keys -f apps/app1/.env
1959
+ ✔ rotated (apps/app1/.env)
1960
+ ```
1536
1961
 
1537
- Set a plaintext key/value.
1962
+ </details>
1963
+ <details><summary>`rotate -k`</summary><br>
1538
1964
 
1539
- ```sh
1540
- $ touch .env
1965
+ Rotate the contents of a specified key inside an encrypted `.env` file.
1541
1966
 
1542
- $ dotenvx set HELLO World --plain
1543
- set HELLO (.env)
1544
- ```
1967
+ ```sh
1968
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1969
+ $ dotenvx encrypt
1970
+ ✔ encrypted (.env)
1971
+ $ dotenvx rotate -k HELLO
1972
+ ✔ rotated (.env)
1973
+ ```
1545
1974
 
1546
- </details>
1547
- * <details><summary>`encrypt`</summary><br>
1975
+ Even specify a glob pattern.
1548
1976
 
1549
- Encrypt the contents of a `.env` file to an encrypted `.env` file.
1977
+ ```sh
1978
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1979
+ $ dotenvx encrypt
1980
+ ✔ encrypted (.env)
1981
+ $ dotenvx rotate -k "HE*"
1982
+ ✔ rotated (.env)
1983
+ ```
1550
1984
 
1551
- ```sh
1552
- $ echo "HELLO=World" > .env
1985
+ </details>
1986
+ <details><summary>`rotate -ek`</summary><br>
1553
1987
 
1554
- $ dotenvx encrypt
1555
- ✔ encrypted (.env)
1556
- ✔ key added to .env.keys (DOTENV_PRIVATE_KEY)
1557
- ⮕ next run [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys
1558
- ⮕ next run [DOTENV_PRIVATE_KEY='122...0b8' dotenvx run -- yourcommand] to test decryption locally
1559
- ```
1988
+ Rotate the encrypted contents inside an encrypted `.env` file except for an excluded key.
1560
1989
 
1561
- </details>
1562
- * <details><summary>`encrypt -f`</summary><br>
1990
+ ```sh
1991
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
1992
+ $ dotenvx encrypt
1993
+ ✔ encrypted (.env)
1994
+ $ dotenvx rotate -ek HOLA
1995
+ ✔ rotated (.env)
1996
+ ```
1563
1997
 
1564
- Encrypt the contents of a specified `.env` file to an encrypted `.env` file.
1998
+ Even specify a glob pattern.
1565
1999
 
1566
- ```sh
1567
- $ echo "HELLO=World" > .env
1568
- $ echo "HELLO=Production" > .env.production
2000
+ ```sh
2001
+ $ echo "HELLO=World\nHOLA=Mundo" > .env
2002
+ $ dotenvx encrypt
2003
+ ✔ encrypted (.env)
2004
+ $ dotenvx rotate -ek "HO*"
2005
+ ✔ rotated (.env)
2006
+ ```
1569
2007
 
1570
- $ dotenvx encrypt -f .env.production
1571
- encrypted (.env.production)
1572
- ✔ key added to .env.keys (DOTENV_PRIVATE_KEY_PRODUCTION)
1573
- ⮕ next run [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys
1574
- ⮕ next run [DOTENV_PRIVATE_KEY='bff...bc4' dotenvx run -- yourcommand] to test decryption locally
1575
- ```
2008
+ </details>
2009
+ <details><summary>`rotate --stdout`</summary><br>
1576
2010
 
1577
- </details>
1578
- * <details><summary>`encrypt -fk`</summary><br>
2011
+ Rotate the contents of an encrypted `.env` file and send to stdout.
1579
2012
 
1580
- Specify path to `.env.keys`. This is useful with monorepos.
2013
+ ```sh
2014
+ $ dotenvx rotate --stdout
2015
+ #/-------------------[DOTENV_PUBLIC_KEY]--------------------/
2016
+ #/ public-key encryption for .env files /
2017
+ #/ [how it works](https://dotenvx.com/encryption) /
2018
+ #/----------------------------------------------------------/
2019
+ DOTENV_PUBLIC_KEY="034af93e93708b994c10f236c96ef88e47291066946cce2e8d98c9e02c741ced45"
2020
+ # .env
2021
+ HELLO="encrypted:12345"
2022
+ ```
1581
2023
 
1582
- ```sh
1583
- $ mkdir -p apps/app1
1584
- $ echo "HELLO=World" > apps/app1/.env
2024
+ or send to a file:
1585
2025
 
1586
- $ dotenvx encrypt -fk .env.keys -f apps/app1/.env
1587
- encrypted (apps/app1/.env)
1588
- ```
2026
+ ```sh
2027
+ $ dotenvx rotate --stdout > somefile.txt
2028
+ ```
1589
2029
 
1590
- Put it to use.
2030
+ </details>
2031
+ <details><summary>`help`</summary><br>
1591
2032
 
1592
- ```sh
1593
- $ dotenvx run -fk .env.keys -f apps/app1/.env
1594
- ```
2033
+ Output help for `dotenvx`.
1595
2034
 
1596
- Use with a relative path.
2035
+ ```sh
2036
+ $ dotenvx help
2037
+ Usage: dotenvx run -- yourcommand
2038
+
2039
+ a better dotenv–from the creator of `dotenv`
2040
+
2041
+ Options:
2042
+ -l, --log-level <level> set log level (default: "info")
2043
+ -q, --quiet sets log level to error
2044
+ -v, --verbose sets log level to verbose
2045
+ -d, --debug sets log level to debug
2046
+ -V, --version output the version number
2047
+ -h, --help display help for command
2048
+
2049
+ Commands:
2050
+ run inject env at runtime [dotenvx run -- yourcommand]
2051
+ get [KEY] return a single environment variable
2052
+ set <KEY> <value> set a single environment variable
2053
+ encrypt convert .env file(s) to encrypted .env file(s)
2054
+ decrypt convert encrypted .env file(s) to plain .env file(s)
2055
+ keypair [KEY] print public/private keys for .env file(s)
2056
+ ls [directory] print all .env files in a tree structure
2057
+
2058
+ Advanced:
2059
+ pro 🏆 pro
2060
+ ext 🔌 extensions
2061
+ ```
1597
2062
 
1598
- ```sh
1599
- $ cd apps/app1
1600
- $ dotenvx run -fk ../../.env.keys -f .env
1601
- ```
2063
+ You can get more detailed help per command with `dotenvx help COMMAND`.
1602
2064
 
1603
- </details>
1604
- * <details><summary>`encrypt -k`</summary><br>
2065
+ ```sh
2066
+ $ dotenvx help run
2067
+ Usage: @dotenvx/dotenvx run [options]
1605
2068
 
1606
- Specify the key(s) to encrypt by passing `--key`.
2069
+ inject env at runtime [dotenvx run -- yourcommand]
1607
2070
 
1608
- ```sh
1609
- $ echo "HELLO=World\nHELLO2=Universe" > .env
2071
+ Options:
2072
+ -e, --env <strings...> environment variable(s) set as string (example: "HELLO=World") (default: [])
2073
+ -f, --env-file <paths...> path(s) to your env file(s) (default: [])
2074
+ -fv, --env-vault-file <paths...> path(s) to your .env.vault file(s) (default: [])
2075
+ -o, --overload override existing env variables
2076
+ --convention <name> load a .env convention (available conventions: ['nextjs'])
2077
+ -h, --help display help for command
1610
2078
 
1611
- $ dotenvx encrypt -k HELLO2
1612
- ✔ encrypted (.env)
1613
- ```
2079
+ Examples:
1614
2080
 
1615
- Even specify a glob pattern.
2081
+ $ dotenvx run -- npm run dev
2082
+ $ dotenvx run -- flask --app index run
2083
+ $ dotenvx run -- php artisan serve
2084
+ $ dotenvx run -- bin/rails s
1616
2085
 
1617
- ```sh
1618
- $ echo "HELLO=World\nHOLA=Mundo" > .env
2086
+ Try it:
1619
2087
 
1620
- $ dotenvx encrypt -k "HE*"
1621
- encrypted (.env)
1622
- ```
2088
+ $ echo "HELLO=World" > .env
2089
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1623
2090
 
1624
- </details>
1625
- * <details><summary>`encrypt -ek`</summary><br>
2091
+ $ dotenvx run -- node index.js
2092
+ [dotenvx@1.X.X] injecting env (1) from .env
2093
+ Hello World
2094
+ ```
1626
2095
 
1627
- Specify the key(s) to NOT encrypt by passing `--exclude-key`.
2096
+ </details>
2097
+ <details><summary>`--version`</summary><br>
1628
2098
 
1629
- ```sh
1630
- $ echo "HELLO=World\nHELLO2=Universe" > .env
2099
+ Check current version of `dotenvx`.
1631
2100
 
1632
- $ dotenvx encrypt -ek HELLO
1633
- encrypted (.env)
1634
- ```
2101
+ ```sh
2102
+ $ dotenvx --version
2103
+ X.X.X
2104
+ ```
1635
2105
 
1636
- Even specify a glob pattern.
2106
+ </details>
1637
2107
 
1638
- ```sh
1639
- $ echo "HELLO=World\nHOLA=Mundo" > .env
2108
+ ### Extensions 🔌
1640
2109
 
1641
- $ dotenvx encrypt -ek "HO*"
1642
- ✔ encrypted (.env)
1643
- ```
2110
+ CLI extensions.
1644
2111
 
1645
- </details>
1646
- * <details><summary>`encrypt --stdout`</summary><br>
2112
+ <details><summary>`ext genexample`</summary><br>
1647
2113
 
1648
- Encrypt the contents of a `.env` file and send to stdout.
2114
+ In one command, generate a `.env.example` file from your current `.env` file contents.
1649
2115
 
1650
- ```sh
1651
- $ echo "HELLO=World" > .env
1652
- $ dotenvx encrypt --stdout
1653
- #/-------------------[DOTENV_PUBLIC_KEY]--------------------/
1654
- #/ public-key encryption for .env files /
1655
- #/ [how it works](https://dotenvx.com/encryption) /
1656
- #/----------------------------------------------------------/
1657
- DOTENV_PUBLIC_KEY="034af93e93708b994c10f236c96ef88e47291066946cce2e8d98c9e02c741ced45"
1658
- # .env
1659
- HELLO="encrypted:BDqDBibm4wsYqMpCjTQ6BsDHmMadg9K3dAt+Z9HPMfLEIRVz50hmLXPXRuDBXaJi/LwWYEVUNiq0HISrslzQPaoyS8Lotg3gFWJTsNCdOWnqpjF2xNUX2RQiP05kAbEXM6MWVjDr"
1660
- ```
1661
-
1662
- or send to a file:
1663
-
1664
- ```sh
1665
- $ echo "HELLO=World" > .env
1666
- $ dotenvx encrypt --stdout > somefile.txt
1667
- ```
2116
+ ```sh
2117
+ $ echo "HELLO=World" > .env
1668
2118
 
1669
- </details>
1670
- * <details><summary>`decrypt`</summary><br>
2119
+ $ dotenvx ext genexample
2120
+ updated .env.example (1)
2121
+ ```
1671
2122
 
1672
- Decrypt the contents of an encrypted `.env` file to an unencrypted `.env` file.
2123
+ ```ini
2124
+ # .env.example
2125
+ HELLO=""
2126
+ ```
1673
2127
 
1674
- ```sh
1675
- $ echo "HELLO=World" > .env
1676
- $ dotenvx encrypt
1677
- ✔ encrypted (.env)
1678
- $ dotenvx decrypt
1679
- ✔ decrypted (.env)
1680
- ```
2128
+ </details>
2129
+ <details><summary>`ext genexample -f`</summary><br>
1681
2130
 
1682
- </details>
1683
- * <details><summary>`decrypt -f`</summary><br>
2131
+ Pass multiple `.env` files to generate your `.env.example` file from the combination of their contents.
1684
2132
 
1685
- Decrypt the contents of a specified encrypted `.env` file to an unencrypted `.env` file.
2133
+ ```sh
2134
+ $ echo "HELLO=World" > .env
2135
+ $ echo "DB_HOST=example.com" > .env.production
1686
2136
 
1687
- ```sh
1688
- $ echo "HELLO=World" > .env
1689
- $ echo "HELLO=Production" > .env.production
1690
-
1691
- $ dotenvx encrypt -f .env.production
1692
- ✔ encrypted (.env.production)
1693
- $ dotenvx decrypt -f .env.production
1694
- ✔ decrypted (.env.production)
1695
- ```
1696
-
1697
- </details>
1698
- * <details><summary>`decrypt -fk`</summary><br>
1699
-
1700
- Specify path to `.env.keys`. This is useful with monorepos.
1701
-
1702
- ```sh
1703
- $ mkdir -p apps/app1
1704
- $ echo "HELLO=World" > apps/app1/.env
1705
-
1706
- $ dotenvx encrypt -fk .env.keys -f apps/app1/.env
1707
- ✔ encrypted (apps/app1/.env)
1708
- $ dotenvx decrypt -fk .env.keys -f apps/app1/.env
1709
- ✔ decrypted (apps/app1/.env)
1710
- ```
1711
-
1712
- </details>
1713
- * <details><summary>`decrypt -k`</summary><br>
1714
-
1715
- Decrypt the contents of a specified key inside an encrypted `.env` file.
1716
-
1717
- ```sh
1718
- $ echo "HELLO=World\nHOLA=Mundo" > .env
1719
- $ dotenvx encrypt
1720
- ✔ encrypted (.env)
1721
- $ dotenvx decrypt -k HELLO
1722
- ✔ decrypted (.env)
1723
- ```
1724
-
1725
- Even specify a glob pattern.
1726
-
1727
- ```sh
1728
- $ echo "HELLO=World\nHOLA=Mundo" > .env
1729
- $ dotenvx encrypt
1730
- ✔ encrypted (.env)
1731
- $ dotenvx decrypt -k "HE*"
1732
- ✔ encrypted (.env)
1733
- ```
1734
-
1735
- </details>
1736
- * <details><summary>`decrypt -ek`</summary><br>
1737
-
1738
- Decrypt the contents inside an encrypted `.env` file except for an excluded key.
1739
-
1740
- ```sh
1741
- $ echo "HELLO=World\nHOLA=Mundo" > .env
1742
- $ dotenvx encrypt
1743
- ✔ encrypted (.env)
1744
- $ dotenvx decrypt -ek HOLA
1745
- ✔ decrypted (.env)
1746
- ```
1747
-
1748
- Even specify a glob pattern.
1749
-
1750
- ```sh
1751
- $ echo "HELLO=World\nHOLA=Mundo" > .env
1752
- $ dotenvx encrypt
1753
- ✔ encrypted (.env)
1754
- $ dotenvx decrypt -ek "HO*"
1755
- ✔ encrypted (.env)
1756
- ```
1757
-
1758
- </details>
1759
- * <details><summary>`decrypt --stdout`</summary><br>
1760
-
1761
- Decrypt the contents of an encrypted `.env` file and send to stdout.
1762
-
1763
- ```sh
1764
- $ dotenvx decrypt --stdout
1765
- #/-------------------[DOTENV_PUBLIC_KEY]--------------------/
1766
- #/ public-key encryption for .env files /
1767
- #/ [how it works](https://dotenvx.com/encryption) /
1768
- #/----------------------------------------------------------/
1769
- DOTENV_PUBLIC_KEY="034af93e93708b994c10f236c96ef88e47291066946cce2e8d98c9e02c741ced45"
1770
- # .env
1771
- HELLO="World"
1772
- ```
1773
-
1774
- or send to a file:
1775
-
1776
- ```sh
1777
- $ dotenvx decrypt --stdout > somefile.txt
1778
- ```
1779
-
1780
- </details>
1781
- * <details><summary>`keypair`</summary><br>
1782
-
1783
- Print public/private keys for `.env` file.
1784
-
1785
- ```sh
1786
- $ echo "HELLO=World" > .env
1787
- $ dotenvx encrypt
2137
+ $ dotenvx ext genexample -f .env -f .env.production
2138
+ updated .env.example (2)
2139
+ ```
1788
2140
 
1789
- $ dotenvx keypair
1790
- {"DOTENV_PUBLIC_KEY":"<publicKey>","DOTENV_PRIVATE_KEY":"<privateKey>"}
1791
- ```
2141
+ ```ini
2142
+ # .env.example
2143
+ HELLO=""
2144
+ DB_HOST=""
2145
+ ```
1792
2146
 
1793
- </details>
1794
- * <details><summary>`keypair -f`</summary><br>
2147
+ </details>
2148
+ <details><summary>`ext genexample directory`</summary><br>
1795
2149
 
1796
- Print public/private keys for `.env.production` file.
2150
+ Generate a `.env.example` file inside the specified directory. Useful for monorepos.
1797
2151
 
1798
- ```sh
1799
- $ echo "HELLO=Production" > .env.production
1800
- $ dotenvx encrypt -f .env.production
2152
+ ```sh
2153
+ $ echo "HELLO=World" > .env
2154
+ $ mkdir -p apps/backend
2155
+ $ echo "HELLO=Backend" > apps/backend/.env
1801
2156
 
1802
- $ dotenvx keypair -f .env.production
1803
- {"DOTENV_PUBLIC_KEY_PRODUCTION":"<publicKey>","DOTENV_PRIVATE_KEY_PRODUCTION":"<privateKey>"}
1804
- ```
2157
+ $ dotenvx ext genexample apps/backend
2158
+ ✔ updated .env.example (1)
2159
+ ```
1805
2160
 
1806
- </details>
1807
- * <details><summary>`keypair -fk`</summary><br>
2161
+ ```ini
2162
+ # apps/backend/.env.example
2163
+ HELLO=""
2164
+ ```
1808
2165
 
1809
- Specify path to `.env.keys`. This is useful for printing public/private keys for monorepos.
2166
+ </details>
2167
+ <details><summary>`ext gitignore`</summary><br>
1810
2168
 
1811
- ```sh
1812
- $ mkdir -p apps/app1
1813
- $ echo "HELLO=World" > apps/app1/.env
1814
- $ dotenvx encrypt -fk .env.keys -f apps/app1/.env
2169
+ Gitignore your `.env` files.
1815
2170
 
1816
- $ dotenvx keypair -fk .env.keys -f apps/app1/.env
1817
- {"DOTENV_PUBLIC_KEY":"<publicKey>","DOTENV_PRIVATE_KEY":"<privateKey>"}
1818
- ```
2171
+ ```sh
2172
+ $ dotenvx ext gitignore
2173
+ ✔ ignored .env* (.gitignore)
2174
+ ```
1819
2175
 
1820
- </details>
1821
- * <details><summary>`keypair DOTENV_PRIVATE_KEY`</summary><br>
2176
+ </details>
2177
+ <details><summary>`ext gitignore --pattern`</summary><br>
1822
2178
 
1823
- Print specific keypair for `.env` file.
2179
+ Gitignore specific pattern(s) of `.env` files.
1824
2180
 
1825
- ```sh
1826
- $ echo "HELLO=World" > .env
1827
- $ dotenvx encrypt
2181
+ ```sh
2182
+ $ dotenvx ext gitignore --pattern .env.keys
2183
+ ignored .env.keys (.gitignore)
2184
+ ```
1828
2185
 
1829
- $ dotenvx keypair DOTENV_PRIVATE_KEY
1830
- <privateKey>
1831
- ```
2186
+ </details>
2187
+ <details><summary>`ext precommit`</summary><br>
1832
2188
 
1833
- </details>
1834
- * <details><summary>`keypair --format shell`</summary><br>
2189
+ Prevent `.env` files from being committed to code.
1835
2190
 
1836
- Print a shell formatted response of public/private keys.
2191
+ ```sh
2192
+ $ dotenvx ext precommit
2193
+ [dotenvx][precommit] .env files (1) protected (encrypted or gitignored)
2194
+ ```
1837
2195
 
1838
- ```sh
1839
- $ echo "HELLO=World" > .env
1840
- $ dotenx encrypt
1841
-
1842
- $ dotenvx keypair --format shell
1843
- DOTENV_PUBLIC_KEY=<publicKey> DOTENV_PRIVATE_KEY=<privateKey>
1844
- ```
1845
-
1846
- </details>
1847
- * <details><summary>`ls`</summary><br>
1848
-
1849
- Print all `.env` files in a tree structure.
1850
-
1851
- ```sh
1852
- $ touch .env
1853
- $ touch .env.production
1854
- $ mkdir -p apps/backend
1855
- $ touch apps/backend/.env
1856
-
1857
- $ dotenvx ls
1858
- ├─ .env.production
1859
- ├─ .env
1860
- └─ apps
1861
- └─ backend
1862
- └─ .env
1863
- ```
1864
-
1865
- </details>
1866
- * <details><summary>`ls directory`</summary><br>
1867
-
1868
- Print all `.env` files inside a specified path to a directory.
1869
-
1870
- ```sh
1871
- $ touch .env
1872
- $ touch .env.production
1873
- $ mkdir -p apps/backend
1874
- $ touch apps/backend/.env
1875
-
1876
- $ dotenvx ls apps/backend
1877
- └─ .env
1878
- ```
1879
-
1880
- </details>
1881
- * <details><summary>`ls -f`</summary><br>
1882
-
1883
- Glob `.env` filenames matching a wildcard.
1884
-
1885
- ```sh
1886
- $ touch .env
1887
- $ touch .env.production
1888
- $ mkdir -p apps/backend
1889
- $ touch apps/backend/.env
1890
- $ touch apps/backend/.env.prod
1891
-
1892
- $ dotenvx ls -f **/.env.prod*
1893
- ├─ .env.production
1894
- └─ apps
1895
- └─ backend
1896
- └─ .env.prod
1897
- ```
1898
-
1899
- </details>
1900
- * <details><summary>`ls -ef`</summary><br>
1901
-
1902
- Glob `.env` filenames excluding a wildcard.
1903
-
1904
- ```sh
1905
- $ touch .env
1906
- $ touch .env.production
1907
- $ mkdir -p apps/backend
1908
- $ touch apps/backend/.env
1909
- $ touch apps/backend/.env.prod
1910
-
1911
- $ dotenvx ls -ef '**/.env.prod*'
1912
- ├─ .env
1913
- └─ apps
1914
- └─ backend
1915
- └─ .env
1916
- ```
1917
-
1918
- </details>
1919
- * <details><summary>`rotate`</summary><br>
1920
-
1921
- Rotate public/private keys for `.env` file and re-encrypt all encrypted values.
1922
-
1923
- ```sh
1924
- $ echo "HELLO=World" > .env
1925
- $ dotenvx encrypt
1926
- ✔ encrypted (.env)
1927
- $ dotenvx rotate
1928
- ✔ rotated (.env)
1929
- ```
2196
+ </details>
2197
+ <details><summary>`ext precommit --install`</summary><br>
1930
2198
 
1931
- </details>
1932
- * <details><summary>`rotate -f`</summary><br>
2199
+ Install a shell script to `.git/hooks/pre-commit` to prevent accidentally committing any `.env` files to source control.
1933
2200
 
1934
- Rotate public/private keys for a specified encrypted `.env` file and re-encrypt all encrypted values.
2201
+ ```sh
2202
+ $ dotenvx ext precommit --install
2203
+ [dotenvx][precommit] dotenvx ext precommit installed [.git/hooks/pre-commit]
2204
+ ```
1935
2205
 
1936
- ```sh
1937
- $ echo "HELLO=World" > .env
1938
- $ echo "HELLO=Production" > .env.production
2206
+ </details>
2207
+ <details><summary>`ext precommit directory`</summary><br>
1939
2208
 
1940
- $ dotenvx encrypt -f .env.production
1941
- ✔ encrypted (.env.production)
1942
- $ dotenvx rotate -f .env.production
1943
- ✔ rotated (.env.production)
1944
- ```
1945
-
1946
- </details>
1947
- * <details><summary>`rotate -fk`</summary><br>
1948
-
1949
- Specify path to `.env.keys`. This is useful with monorepos.
1950
-
1951
- ```sh
1952
- $ mkdir -p apps/app1
1953
- $ echo "HELLO=World" > apps/app1/.env
1954
-
1955
- $ dotenvx encrypt -fk .env.keys -f apps/app1/.env
1956
- ✔ encrypted (apps/app1/.env)
1957
- $ dotenvx rotate -fk .env.keys -f apps/app1/.env
1958
- ✔ rotated (apps/app1/.env)
1959
- ```
1960
-
1961
- </details>
1962
- * <details><summary>`rotate -k`</summary><br>
1963
-
1964
- Rotate the contents of a specified key inside an encrypted `.env` file.
1965
-
1966
- ```sh
1967
- $ echo "HELLO=World\nHOLA=Mundo" > .env
1968
- $ dotenvx encrypt
1969
- ✔ encrypted (.env)
1970
- $ dotenvx rotate -k HELLO
1971
- ✔ rotated (.env)
1972
- ```
1973
-
1974
- Even specify a glob pattern.
1975
-
1976
- ```sh
1977
- $ echo "HELLO=World\nHOLA=Mundo" > .env
1978
- $ dotenvx encrypt
1979
- ✔ encrypted (.env)
1980
- $ dotenvx rotate -k "HE*"
1981
- ✔ rotated (.env)
1982
- ```
1983
-
1984
- </details>
1985
- * <details><summary>`rotate -ek`</summary><br>
1986
-
1987
- Rotate the encrypted contents inside an encrypted `.env` file except for an excluded key.
1988
-
1989
- ```sh
1990
- $ echo "HELLO=World\nHOLA=Mundo" > .env
1991
- $ dotenvx encrypt
1992
- ✔ encrypted (.env)
1993
- $ dotenvx rotate -ek HOLA
1994
- ✔ rotated (.env)
1995
- ```
1996
-
1997
- Even specify a glob pattern.
1998
-
1999
- ```sh
2000
- $ echo "HELLO=World\nHOLA=Mundo" > .env
2001
- $ dotenvx encrypt
2002
- ✔ encrypted (.env)
2003
- $ dotenvx rotate -ek "HO*"
2004
- ✔ rotated (.env)
2005
- ```
2006
-
2007
- </details>
2008
- * <details><summary>`rotate --stdout`</summary><br>
2009
-
2010
- Rotate the contents of an encrypted `.env` file and send to stdout.
2011
-
2012
- ```sh
2013
- $ dotenvx rotate --stdout
2014
- #/-------------------[DOTENV_PUBLIC_KEY]--------------------/
2015
- #/ public-key encryption for .env files /
2016
- #/ [how it works](https://dotenvx.com/encryption) /
2017
- #/----------------------------------------------------------/
2018
- DOTENV_PUBLIC_KEY="034af93e93708b994c10f236c96ef88e47291066946cce2e8d98c9e02c741ced45"
2019
- # .env
2020
- HELLO="encrypted:12345"
2021
- ```
2022
-
2023
- or send to a file:
2024
-
2025
- ```sh
2026
- $ dotenvx rotate --stdout > somefile.txt
2027
- ```
2028
-
2029
- </details>
2030
- * <details><summary>`help`</summary><br>
2031
-
2032
- Output help for `dotenvx`.
2033
-
2034
- ```sh
2035
- $ dotenvx help
2036
- Usage: dotenvx run -- yourcommand
2037
-
2038
- a better dotenv–from the creator of `dotenv`
2039
-
2040
- Options:
2041
- -l, --log-level <level> set log level (default: "info")
2042
- -q, --quiet sets log level to error
2043
- -v, --verbose sets log level to verbose
2044
- -d, --debug sets log level to debug
2045
- -V, --version output the version number
2046
- -h, --help display help for command
2047
-
2048
- Commands:
2049
- run inject env at runtime [dotenvx run -- yourcommand]
2050
- get [KEY] return a single environment variable
2051
- set <KEY> <value> set a single environment variable
2052
- encrypt convert .env file(s) to encrypted .env file(s)
2053
- decrypt convert encrypted .env file(s) to plain .env file(s)
2054
- keypair [KEY] print public/private keys for .env file(s)
2055
- ls [directory] print all .env files in a tree structure
2056
-
2057
- Advanced:
2058
- pro 🏆 pro
2059
- ext 🔌 extensions
2060
- ```
2061
-
2062
- You can get more detailed help per command with `dotenvx help COMMAND`.
2063
-
2064
- ```sh
2065
- $ dotenvx help run
2066
- Usage: @dotenvx/dotenvx run [options]
2067
-
2068
- inject env at runtime [dotenvx run -- yourcommand]
2069
-
2070
- Options:
2071
- -e, --env <strings...> environment variable(s) set as string (example: "HELLO=World") (default: [])
2072
- -f, --env-file <paths...> path(s) to your env file(s) (default: [])
2073
- -fv, --env-vault-file <paths...> path(s) to your .env.vault file(s) (default: [])
2074
- -o, --overload override existing env variables
2075
- --convention <name> load a .env convention (available conventions: ['nextjs'])
2076
- -h, --help display help for command
2077
-
2078
- Examples:
2079
-
2080
- $ dotenvx run -- npm run dev
2081
- $ dotenvx run -- flask --app index run
2082
- $ dotenvx run -- php artisan serve
2083
- $ dotenvx run -- bin/rails s
2084
-
2085
- Try it:
2086
-
2087
- $ echo "HELLO=World" > .env
2088
- $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
2089
-
2090
- $ dotenvx run -- node index.js
2091
- [dotenvx@1.X.X] injecting env (1) from .env
2092
- Hello World
2093
- ```
2094
-
2095
- </details>
2096
- * <details><summary>`--version`</summary><br>
2097
-
2098
- Check current version of `dotenvx`.
2099
-
2100
- ```sh
2101
- $ dotenvx --version
2102
- X.X.X
2103
- ```
2209
+ Prevent `.env` files from being committed to code inside a specified path to a directory.
2104
2210
 
2105
- </details>
2211
+ ```sh
2212
+ $ echo "HELLO=World" > .env
2213
+ $ mkdir -p apps/backend
2214
+ $ echo "HELLO=Backend" > apps/backend/.env
2106
2215
 
2107
- ### Extensions 🔌
2216
+ $ dotenvx ext precommit apps/backend
2217
+ [dotenvx][precommit] apps/backend/.env not protected (encrypted or gitignored)
2218
+ ```
2108
2219
 
2109
- CLI extensions.
2220
+ </details>
2221
+ <details><summary>`ext prebuild`</summary><br>
2110
2222
 
2111
- * <details><summary>`ext genexample`</summary><br>
2223
+ Prevent `.env` files from being built into your docker containers.
2112
2224
 
2113
- In one command, generate a `.env.example` file from your current `.env` file contents.
2225
+ Add it to your `Dockerfile`.
2114
2226
 
2115
- ```sh
2116
- $ echo "HELLO=World" > .env
2227
+ ```sh
2228
+ # Dockerfile
2229
+ RUN curl -fsS https://dotenvx.sh | sh
2117
2230
 
2118
- $ dotenvx ext genexample
2119
- ✔ updated .env.example (1)
2120
- ```
2231
+ ...
2121
2232
 
2122
- ```ini
2123
- # .env.example
2124
- HELLO=""
2125
- ```
2233
+ RUN dotenvx ext prebuild
2234
+ CMD ["dotenvx", "run", "--", "node", "index.js"]
2235
+ ```
2126
2236
 
2127
- </details>
2128
- * <details><summary>`ext genexample -f`</summary><br>
2237
+ </details>
2238
+ <details><summary>`ext prebuild directory`</summary><br>
2129
2239
 
2130
- Pass multiple `.env` files to generate your `.env.example` file from the combination of their contents.
2240
+ Prevent `.env` files from being built into your docker containers inside a specified path to a directory.
2131
2241
 
2132
- ```sh
2133
- $ echo "HELLO=World" > .env
2134
- $ echo "DB_HOST=example.com" > .env.production
2242
+ Add it to your `Dockerfile`.
2135
2243
 
2136
- $ dotenvx ext genexample -f .env -f .env.production
2137
- updated .env.example (2)
2138
- ```
2244
+ ```sh
2245
+ # Dockerfile
2246
+ RUN curl -fsS https://dotenvx.sh | sh
2139
2247
 
2140
- ```ini
2141
- # .env.example
2142
- HELLO=""
2143
- DB_HOST=""
2144
- ```
2248
+ ...
2145
2249
 
2146
- </details>
2147
- * <details><summary>`ext genexample directory`</summary><br>
2250
+ RUN dotenvx ext prebuild apps/backend
2251
+ CMD ["dotenvx", "run", "--", "node", "apps/backend/index.js"]
2252
+ ```
2148
2253
 
2149
- Generate a `.env.example` file inside the specified directory. Useful for monorepos.
2254
+ </details>
2255
+ <details><summary>`ext scan`</summary><br>
2150
2256
 
2151
- ```sh
2152
- $ echo "HELLO=World" > .env
2153
- $ mkdir -p apps/backend
2154
- $ echo "HELLO=Backend" > apps/backend/.env
2257
+ Scan for leaked secrets.
2155
2258
 
2156
- $ dotenvx ext genexample apps/backend
2157
- updated .env.example (1)
2158
- ```
2259
+ ```sh
2260
+ $ dotenvx ext scan
2261
+ 100 commits scanned.
2262
+ no leaks found
2263
+ ```
2159
2264
 
2160
- ```ini
2161
- # apps/backend/.env.example
2162
- HELLO=""
2163
- ```
2265
+ Uses [gitleaks](https://gitleaks.io) under the hood.
2164
2266
 
2165
- </details>
2166
- * <details><summary>`ext gitignore`</summary><br>
2267
+ </details>
2167
2268
 
2168
- Gitignore your `.env` files.
2269
+ ### Library 📦
2169
2270
 
2170
- ```sh
2171
- $ dotenvx ext gitignore
2172
- ✔ ignored .env* (.gitignore)
2173
- ```
2271
+ Use dotenvx directly in code.
2174
2272
 
2175
- </details>
2176
- * <details><summary>`ext gitignore --pattern`</summary><br>
2273
+ <details><summary>`config()`</summary><br>
2177
2274
 
2178
- Gitignore specific pattern(s) of `.env` files.
2275
+ Use directly in node.js code.
2179
2276
 
2180
- ```sh
2181
- $ dotenvx ext gitignore --pattern .env.keys
2182
- ✔ ignored .env.keys (.gitignore)
2183
- ```
2277
+ ```ini
2278
+ # .env
2279
+ HELLO="World"
2280
+ ```
2184
2281
 
2185
- </details>
2186
- * <details><summary>`ext precommit`</summary><br>
2282
+ ```js
2283
+ // index.js
2284
+ require('@dotenvx/dotenvx').config()
2187
2285
 
2188
- Prevent `.env` files from being committed to code.
2286
+ console.log(`Hello ${process.env.HELLO}`)
2287
+ ```
2189
2288
 
2190
- ```sh
2191
- $ dotenvx ext precommit
2192
- [dotenvx][precommit] .env files (1) protected (encrypted or gitignored)
2193
- ```
2289
+ ```sh
2290
+ $ node index.js
2291
+ [dotenvx@1.X.X] injecting env (1) from .env
2292
+ Hello World
2293
+ ```
2194
2294
 
2195
- </details>
2196
- * <details><summary>`ext precommit --install`</summary><br>
2295
+ It defaults to looking for a `.env` file.
2197
2296
 
2198
- Install a shell script to `.git/hooks/pre-commit` to prevent accidentally committing any `.env` files to source control.
2297
+ </details>
2298
+ <details><summary>`config(path: ['.env.local', '.env'])` - multiple files</summary><br>
2199
2299
 
2200
- ```sh
2201
- $ dotenvx ext precommit --install
2202
- [dotenvx][precommit] dotenvx ext precommit installed [.git/hooks/pre-commit]
2203
- ```
2300
+ Specify path(s) to multiple .env files.
2204
2301
 
2205
- </details>
2206
- * <details><summary>`ext precommit directory`</summary><br>
2302
+ ```ini
2303
+ # .env.local
2304
+ HELLO="Me"
2305
+ ```
2207
2306
 
2208
- Prevent `.env` files from being committed to code inside a specified path to a directory.
2307
+ ```ini
2308
+ # .env
2309
+ HELLO="World"
2310
+ ```
2209
2311
 
2210
- ```sh
2211
- $ echo "HELLO=World" > .env
2212
- $ mkdir -p apps/backend
2213
- $ echo "HELLO=Backend" > apps/backend/.env
2214
-
2215
- $ dotenvx ext precommit apps/backend
2216
- [dotenvx][precommit] apps/backend/.env not protected (encrypted or gitignored)
2217
- ```
2312
+ ```js
2313
+ // index.js
2314
+ require('@dotenvx/dotenvx').config({path: ['.env.local', '.env']})
2218
2315
 
2219
- </details>
2220
- * <details><summary>`ext prebuild`</summary><br>
2316
+ // esm
2317
+ // import dotenvx from "@dotenvx/dotenvx";
2318
+ // dotenvx.config({path: ['.env.local', '.env']});
2221
2319
 
2222
- Prevent `.env` files from being built into your docker containers.
2320
+ console.log(`Hello ${process.env.HELLO}`)
2321
+ ```
2223
2322
 
2224
- Add it to your `Dockerfile`.
2323
+ ```sh
2324
+ $ node index.js
2325
+ [dotenvx@1.X.X] injecting env (1) from .env.local, .env
2326
+ Hello Me
2327
+ ```
2225
2328
 
2226
- ```sh
2227
- # Dockerfile
2228
- RUN curl -fsS https://dotenvx.sh | sh
2329
+ </details>
2330
+ <details><summary>`config(overload: true)` - overload</summary><br>
2229
2331
 
2230
- ...
2332
+ Use `overload` to overwrite the prior set value.
2231
2333
 
2232
- RUN dotenvx ext prebuild
2233
- CMD ["dotenvx", "run", "--", "node", "index.js"]
2234
- ```
2334
+ ```ini
2335
+ # .env.local
2336
+ HELLO="Me"
2337
+ ```
2235
2338
 
2236
- </details>
2237
- * <details><summary>`ext prebuild directory`</summary><br>
2339
+ ```ini
2340
+ # .env
2341
+ HELLO="World"
2342
+ ```
2238
2343
 
2239
- Prevent `.env` files from being built into your docker containers inside a specified path to a directory.
2344
+ ```js
2345
+ // index.js
2346
+ require('@dotenvx/dotenvx').config({path: ['.env.local', '.env'], overload: true})
2240
2347
 
2241
- Add it to your `Dockerfile`.
2348
+ // esm
2349
+ // import dotenvx from "@dotenvx/dotenvx";
2350
+ // dotenvx.config({path: ['.env.local', '.env'], overload: true});
2242
2351
 
2243
- ```sh
2244
- # Dockerfile
2245
- RUN curl -fsS https://dotenvx.sh | sh
2352
+ console.log(`Hello ${process.env.HELLO}`)
2353
+ ```
2246
2354
 
2247
- ...
2355
+ ```sh
2356
+ $ node index.js
2357
+ [dotenvx@1.X.X] injecting env (1) from .env.local, .env
2358
+ Hello World
2359
+ ```
2248
2360
 
2249
- RUN dotenvx ext prebuild apps/backend
2250
- CMD ["dotenvx", "run", "--", "node", "apps/backend/index.js"]
2251
- ```
2361
+ </details>
2362
+ <details><summary>`config(quiet: true)` - quiet</summary><br>
2252
2363
 
2253
- </details>
2254
- * <details><summary>`ext scan`</summary><br>
2364
+ Suppress all output (except errors).
2255
2365
 
2256
- Scan for leaked secrets.
2366
+ ```ini
2367
+ # .env
2368
+ HELLO="World"
2369
+ ```
2257
2370
 
2258
- ```sh
2259
- $ dotenvx ext scan
2260
- 100 commits scanned.
2261
- no leaks found
2262
- ```
2371
+ ```js
2372
+ // index.js
2373
+ require('@dotenvx/dotenvx').config({path: ['.env.missing', '.env'], quiet: true})
2263
2374
 
2264
- Uses [gitleaks](https://gitleaks.io) under the hood.
2375
+ // esm
2376
+ // import dotenvx from "@dotenvx/dotenvx";
2377
+ // dotenvx.config({path: ['.env.missing', '.env'], quiet: true});
2265
2378
 
2266
- </details>
2379
+ console.log(`Hello ${process.env.HELLO}`)
2380
+ ```
2267
2381
 
2268
- ### Library 📦
2382
+ ```sh
2383
+ $ node index.js
2384
+ Error: [MISSING_ENV_FILE] missing .env.missing file (/path/to/.env.missing)
2385
+ Hello World
2386
+ ```
2269
2387
 
2270
- Use dotenvx directly in code.
2388
+ </details>
2389
+ <details><summary>`config(strict: true)` - strict</summary><br>
2271
2390
 
2272
- * <details><summary>`config()`</summary><br>
2391
+ Exit with code `1` if any errors are encountered - like a missing .env file or decryption failure.
2273
2392
 
2274
- Use directly in node.js code.
2393
+ ```ini
2394
+ # .env
2395
+ HELLO="World"
2396
+ ```
2275
2397
 
2276
- ```ini
2277
- # .env
2278
- HELLO="World"
2279
- ```
2398
+ ```js
2399
+ // index.js
2400
+ require('@dotenvx/dotenvx').config({path: ['.env.missing', '.env'], strict: true})
2280
2401
 
2281
- ```js
2282
- // index.js
2283
- require('@dotenvx/dotenvx').config()
2402
+ // esm
2403
+ // import dotenvx from "@dotenvx/dotenvx";
2404
+ // dotenvx.config({path: ['.env.missing', '.env'], strict: true});
2284
2405
 
2285
- console.log(`Hello ${process.env.HELLO}`)
2286
- ```
2406
+ console.log(`Hello ${process.env.HELLO}`)
2407
+ ```
2287
2408
 
2288
- ```sh
2289
- $ node index.js
2290
- [dotenvx@1.X.X] injecting env (1) from .env
2291
- Hello World
2292
- ```
2409
+ ```sh
2410
+ $ node index.js
2411
+ Error: [MISSING_ENV_FILE] missing .env.missing file (/path/to/.env.missing)
2412
+ ```
2293
2413
 
2294
- It defaults to looking for a `.env` file.
2414
+ </details>
2415
+ <details><summary>`config(ignore:)` - ignore</summary><br>
2295
2416
 
2296
- </details>
2297
- * <details><summary>`config(path: ['.env.local', '.env'])` - multiple files</summary><br>
2417
+ Use `ignore` to suppress specific errors like `MISSING_ENV_FILE`.
2298
2418
 
2299
- Specify path(s) to multiple .env files.
2419
+ ```ini
2420
+ # .env
2421
+ HELLO="World"
2422
+ ```
2300
2423
 
2301
- ```ini
2302
- # .env.local
2303
- HELLO="Me"
2304
- ```
2424
+ ```js
2425
+ // index.js
2426
+ require('@dotenvx/dotenvx').config({path: ['.env.missing', '.env'], ignore: ['MISSING_ENV_FILE']})
2305
2427
 
2306
- ```ini
2307
- # .env
2308
- HELLO="World"
2309
- ```
2428
+ // esm
2429
+ // import dotenvx from "@dotenvx/dotenvx";
2430
+ // dotenvx.config({path: ['.env.missing', '.env'], ignore: ['MISSING_ENV_FILE']});
2310
2431
 
2311
- ```js
2312
- // index.js
2313
- require('@dotenvx/dotenvx').config({path: ['.env.local', '.env']})
2432
+ console.log(`Hello ${process.env.HELLO}`)
2433
+ ```
2314
2434
 
2315
- // esm
2316
- // import dotenvx from "@dotenvx/dotenvx";
2317
- // dotenvx.config({path: ['.env.local', '.env']});
2435
+ ```sh
2436
+ $ node index.js
2437
+ [dotenvx@1.X.X] injecting env (1) from .env
2438
+ Hello World
2439
+ ```
2318
2440
 
2319
- console.log(`Hello ${process.env.HELLO}`)
2320
- ```
2441
+ </details>
2442
+ <details><summary>`config(envKeysFile:)` - envKeysFile</summary><br>
2321
2443
 
2322
- ```sh
2323
- $ node index.js
2324
- [dotenvx@1.X.X] injecting env (1) from .env.local, .env
2325
- Hello Me
2326
- ```
2444
+ Use `envKeysFile` to customize the path to your `.env.keys` file. This is useful with monorepos.
2327
2445
 
2328
- </details>
2329
- * <details><summary>`config(overload: true)` - overload</summary><br>
2446
+ ```ini
2447
+ # .env
2448
+ HELLO="World"
2449
+ ```
2330
2450
 
2331
- Use `overload` to overwrite the prior set value.
2451
+ ```js
2452
+ // index.js
2453
+ require('@dotenvx/dotenvx').config({path: ['.env'], envKeysFile: '../../.env.keys'})
2454
+ ```
2332
2455
 
2333
- ```ini
2334
- # .env.local
2335
- HELLO="Me"
2336
- ```
2456
+ </details>
2457
+ <details><summary>`parse(src)`</summary><br>
2337
2458
 
2338
- ```ini
2339
- # .env
2340
- HELLO="World"
2341
- ```
2459
+ Parse a `.env` string directly in node.js code.
2342
2460
 
2343
- ```js
2344
- // index.js
2345
- require('@dotenvx/dotenvx').config({path: ['.env.local', '.env'], overload: true})
2461
+ ```js
2462
+ // index.js
2463
+ const dotenvx = require('@dotenvx/dotenvx')
2464
+ const src = 'HELLO=World'
2465
+ const parsed = dotenvx.parse(src)
2466
+ console.log(`Hello ${parsed.HELLO}`)
2467
+ ```
2346
2468
 
2347
- // esm
2348
- // import dotenvx from "@dotenvx/dotenvx";
2349
- // dotenvx.config({path: ['.env.local', '.env'], overload: true});
2469
+ ```sh
2470
+ $ node index.js
2471
+ Hello World
2472
+ ```
2350
2473
 
2351
- console.log(`Hello ${process.env.HELLO}`)
2352
- ```
2474
+ </details>
2475
+ <details><summary>`parse(src, {processEnv:})`</summary><br>
2353
2476
 
2354
- ```sh
2355
- $ node index.js
2356
- [dotenvx@1.X.X] injecting env (1) from .env.local, .env
2357
- Hello World
2358
- ```
2477
+ Sometimes, you want to run `parse` without it accessing `process.env`. (You can pass a fake processEnv this way as well - sometimes useful.)
2359
2478
 
2360
- </details>
2361
- * <details><summary>`config(quiet: true)` - quiet</summary><br>
2479
+ ```js
2480
+ // index.js
2481
+ const dotenvx = require('@dotenvx/dotenvx')
2482
+ const src = 'USER=Me'
2483
+ const parsed = dotenvx.parse(src, { processEnv: {} })
2484
+ console.log(`Hello ${parsed.USER}`)
2485
+ ```
2362
2486
 
2363
- Suppress all output (except errors).
2487
+ ```sh
2488
+ $ node index.js
2489
+ Hello Me
2490
+ ```
2364
2491
 
2365
- ```ini
2366
- # .env
2367
- HELLO="World"
2368
- ```
2492
+ </details>
2493
+ <details><summary>`parse(src, {privateKey:})`</summary><br>
2369
2494
 
2370
- ```js
2371
- // index.js
2372
- require('@dotenvx/dotenvx').config({path: ['.env.missing', '.env'], quiet: true})
2495
+ Decrypt an encrypted `.env` string with `privateKey`.
2373
2496
 
2374
- // esm
2375
- // import dotenvx from "@dotenvx/dotenvx";
2376
- // dotenvx.config({path: ['.env.missing', '.env'], quiet: true});
2497
+ ```js
2498
+ // index.js
2499
+ const dotenvx = require('@dotenvx/dotenvx')
2500
+ const src = 'HELLO="encrypted:BE9Y7LKANx77X1pv1HnEoil93fPa5c9rpL/1ps48uaRT9zM8VR6mHx9yM+HktKdsPGIZELuZ7rr2mn1gScsmWitppAgE/1lVprNYBCqiYeaTcKXjDUXU5LfsEsflnAsDhT/kWG1l"'
2501
+ const parsed = dotenvx.parse(src, { privateKey: 'a4547dcd9d3429615a3649bb79e87edb62ee6a74b007075e9141ae44f5fb412c' })
2502
+ console.log(`Hello ${parsed.HELLO}`)
2503
+ ```
2377
2504
 
2378
- console.log(`Hello ${process.env.HELLO}`)
2379
- ```
2505
+ ```sh
2506
+ $ node index.js
2507
+ Hello World
2508
+ ```
2509
+ </details>
2510
+ <details><summary>`set(KEY, value)`</summary><br>
2380
2511
 
2381
- ```sh
2382
- $ node index.js
2383
- Error: [MISSING_ENV_FILE] missing .env.missing file (/path/to/.env.missing)
2384
- Hello World
2385
- ```
2512
+ Programmatically set an environment variable.
2386
2513
 
2387
- </details>
2388
- * <details><summary>`config(strict: true)` - strict</summary><br>
2514
+ ```js
2515
+ // index.js
2516
+ const dotenvx = require('@dotenvx/dotenvx')
2517
+ dotenvx.set('HELLO', 'World', { path: '.env' })
2518
+ ```
2389
2519
 
2390
- Exit with code `1` if any errors are encountered - like a missing .env file or decryption failure.
2520
+ </details>
2521
+ <details><summary>`get(KEY)` - <i>Decryption at Access</i></summary><br>
2391
2522
 
2392
- ```ini
2393
- # .env
2394
- HELLO="World"
2395
- ```
2523
+ Programmatically get an environment variable at access/runtime.
2396
2524
 
2397
- ```js
2398
- // index.js
2399
- require('@dotenvx/dotenvx').config({path: ['.env.missing', '.env'], strict: true})
2525
+ ```js
2526
+ // index.js
2527
+ const dotenvx = require('@dotenvx/dotenvx')
2528
+ const decryptedValue = dotenvx.get('HELLO')
2529
+ console.log(decryptedValue)
2530
+ ```
2400
2531
 
2401
- // esm
2402
- // import dotenvx from "@dotenvx/dotenvx";
2403
- // dotenvx.config({path: ['.env.missing', '.env'], strict: true});
2532
+ This is known as *Decryption at Access* and is written about in [the whitepaper](https://dotenvx.com/dotenvx.pdf).
2404
2533
 
2405
- console.log(`Hello ${process.env.HELLO}`)
2406
- ```
2534
+ </details>
2407
2535
 
2408
- ```sh
2409
- $ node index.js
2410
- Error: [MISSING_ENV_FILE] missing .env.missing file (/path/to/.env.missing)
2411
- ```
2536
+ &nbsp;
2412
2537
 
2413
- </details>
2414
- * <details><summary>`config(ignore:)` - ignore</summary><br>
2538
+ ## Radar 📡
2415
2539
 
2416
- Use `ignore` to suppress specific errors like `MISSING_ENV_FILE`.
2540
+ > [Dotenvx Radar](https://dotenvx.com/radar) is a commercial extension for [dotenvx](https://github.com/dotenvx/dotenvx).
2417
2541
 
2418
- ```ini
2419
- # .env
2420
- HELLO="World"
2421
- ```
2542
+ *Observe, version, and back up your environment variables at runtime.*
2422
2543
 
2423
- ```js
2424
- // index.js
2425
- require('@dotenvx/dotenvx').config({path: ['.env.missing', '.env'], ignore: ['MISSING_ENV_FILE']})
2544
+ ### Usage
2426
2545
 
2427
- // esm
2428
- // import dotenvx from "@dotenvx/dotenvx";
2429
- // dotenvx.config({path: ['.env.missing', '.env'], ignore: ['MISSING_ENV_FILE']});
2546
+ ```sh
2547
+ 1. Install Radar
2430
2548
 
2431
- console.log(`Hello ${process.env.HELLO}`)
2432
- ```
2549
+ $ curl -sfS https://dotenvx.sh/radar | sh
2433
2550
 
2434
- ```sh
2435
- $ node index.js
2436
- [dotenvx@1.X.X] injecting env (1) from .env
2437
- Hello World
2438
- ```
2551
+ 2. Log in
2439
2552
 
2440
- </details>
2441
- * <details><summary>`config(envKeysFile:)` - envKeysFile</summary><br>
2553
+ $ dotenvx-radar login
2554
+ logged in [username]
2442
2555
 
2443
- Use `envKeysFile` to customize the path to your `.env.keys` file. This is useful with monorepos.
2556
+ 3. Run dotenvx
2444
2557
 
2445
- ```ini
2446
- # .env
2447
- HELLO="World"
2448
- ```
2558
+ $ dotenvx run -- yourcommand
2559
+ [dotenvx@1.0.0] 📡 radar active
2560
+ [dotenvx@1.0.0] injecting env (1) from .env
2561
+ ```
2449
2562
 
2450
- ```js
2451
- // index.js
2452
- require('@dotenvx/dotenvx').config({path: ['.env'], envKeysFile: '../../.env.keys'})
2453
- ```
2563
+ That's it! Your environment variables are auto-observed and backed up by [Radar](https://dotenvx.com/radar).
2454
2564
 
2455
- </details>
2456
- * <details><summary>`parse(src)`</summary><br>
2565
+ ### UI
2457
2566
 
2458
- Parse a `.env` string directly in node.js code.
2567
+ ![dotenvx-radar](https://dotenvx.com/radar/ui.png)
2459
2568
 
2460
- ```js
2461
- // index.js
2462
- const dotenvx = require('@dotenvx/dotenvx')
2463
- const src = 'HELLO=World'
2464
- const parsed = dotenvx.parse(src)
2465
- console.log(`Hello ${parsed.HELLO}`)
2466
- ```
2569
+ ### CLI
2467
2570
 
2468
- ```sh
2469
- $ node index.js
2470
- Hello World
2471
- ```
2571
+ <details><summary>`login`</summary><br>
2472
2572
 
2473
- </details>
2474
- * <details><summary>`parse(src, {processEnv:})`</summary><br>
2573
+ Log in to [radar](https://dotenvx.com/radar).
2475
2574
 
2476
- Sometimes, you want to run `parse` without it accessing `process.env`. (You can pass a fake processEnv this way as well - sometimes useful.)
2575
+ ```sh
2576
+ $ dotenvx-radar login
2577
+ press Enter to open [https://radar.dotenvx.com/login/device] and enter code [D9C1-03BC]... (Y/n)
2578
+ ⠹ waiting on browser authorization
2579
+ ✔ logged in [username] to this device and activated token [dxo_6kjPifI…]
2580
+ ```
2477
2581
 
2478
- ```js
2479
- // index.js
2480
- const dotenvx = require('@dotenvx/dotenvx')
2481
- const src = 'USER=Me'
2482
- const parsed = dotenvx.parse(src, { processEnv: {} })
2483
- console.log(`Hello ${parsed.USER}`)
2484
- ```
2582
+ </details>
2583
+ <details><summary>`logout`</summary><br>
2485
2584
 
2486
- ```sh
2487
- $ node index.js
2488
- Hello Me
2489
- ```
2585
+ Log out of [radar](https://dotenvx.com/radar).
2490
2586
 
2491
- </details>
2492
- * <details><summary>`parse(src, {privateKey:})`</summary><br>
2587
+ ```sh
2588
+ $ dotenvx-radar logout
2589
+ ✔ logged out [username] from this device and revoked token [dxo_5ZrwRXV…]
2590
+ ```
2493
2591
 
2494
- Decrypt an encrypted `.env` string with `privateKey`.
2592
+ </details>
2593
+ <details><summary>`status`</summary><br>
2495
2594
 
2496
- ```js
2497
- // index.js
2498
- const dotenvx = require('@dotenvx/dotenvx')
2499
- const src = 'HELLO="encrypted:BE9Y7LKANx77X1pv1HnEoil93fPa5c9rpL/1ps48uaRT9zM8VR6mHx9yM+HktKdsPGIZELuZ7rr2mn1gScsmWitppAgE/1lVprNYBCqiYeaTcKXjDUXU5LfsEsflnAsDhT/kWG1l"'
2500
- const parsed = dotenvx.parse(src, { privateKey: 'a4547dcd9d3429615a3649bb79e87edb62ee6a74b007075e9141ae44f5fb412c' })
2501
- console.log(`Hello ${parsed.HELLO}`)
2502
- ```
2595
+ Check current status of [radar](https://dotenvx.com/radar) - `on` or `off` (logged in or out).
2503
2596
 
2504
- ```sh
2505
- $ node index.js
2506
- Hello World
2507
- ```
2508
- </details>
2509
- * <details><summary>`set(KEY, value)`</summary><br>
2597
+ ```sh
2598
+ $ dotenvx-radar status
2599
+ on
2600
+ ```
2510
2601
 
2511
- Programmatically set an environment variable.
2602
+ </details>
2603
+ <details><summary>`settings`</summary><br>
2512
2604
 
2513
- ```js
2514
- // index.js
2515
- const dotenvx = require('@dotenvx/dotenvx')
2516
- dotenvx.set('HELLO', 'World', { path: '.env' })
2517
- ```
2605
+ Check and configure various settings for [radar](https://dotenvx.com/radar) - `username`, `token`, and more.
2518
2606
 
2519
- </details>
2520
- * <details><summary>`get(KEY)` - <i>Decryption at Access</i></summary><br>
2607
+ ```sh
2608
+ $ dotenvx-radar settings
2609
+ Usage: dotenvx-radar settings [options] [command]
2521
2610
 
2522
- Programmatically get an environment variable at access/runtime.
2611
+ ⚙️ settings
2523
2612
 
2524
- ```js
2525
- // index.js
2526
- const dotenvx = require('@dotenvx/dotenvx')
2527
- const decryptedValue = dotenvx.get('HELLO')
2528
- console.log(decryptedValue)
2529
- ```
2613
+ Options:
2614
+ -h, --help display help for command
2530
2615
 
2531
- This is known as *Decryption at Access* and is written about in [the whitepaper](https://dotenvx.com/dotenvx.pdf).
2616
+ Commands:
2617
+ username print your username
2618
+ token [options] print your access token (--unmask)
2619
+ hostname print hostname
2620
+ help [command] display help for command
2621
+ ```
2532
2622
 
2533
- </details>
2623
+ </details>
2534
2624
 
2535
2625
  &nbsp;
2536
2626